怎么判断一个数组是数组呢?
其实这个也是一个常考的题目. 依稀记得我为数不多的面试经过中都被问道过.
方案一: instanceof
variable instanceof Array
解决思路:
使用类型判断所给的方法 instanceof 进行判断.
此方法返回一个布尔值, 能够精确判断一个对象的类型.
方案二: 原型 prototype + toString + call
Object.prototype.toString.call(variable).indexOf('Array') !== -1;
因为用了 toString 方法, 返回值是一个字符串, 还需要第二层判断, 看字符串中是否有'Array'这个关键字:
这个字符串中有 Array 关键字的返回了数字 8(就是 Array 这个字符在整个 "[object Array]" 中出现的下标数).
如果变量对象不是一个纯数组, 那么返回的数字就是 - 1. 因为 indexOf 方法在字符串中找不到指定字符就会返回 - 1.
所以最后还需要通过比对数值是否等于 - 1 就能判断是否是数组类型:
true 就是了.
这里可能难以理解的是 call 方法, 毕竟前边 toString 他们都各司其职.
首先我们打印出来对象原型上的 toString 方法返回什么:
这里涉及到 Object.prototype.toString()的原理. 由于我还学的不深入, 就不做总结了,
具体可以看这篇总结的不错:[传送门 https://www.jb51.net/article/79941.htm ]
大致意思有:
调用 toString 时会将 this 对象的 [[class]] 属性值拿到, 而这个属性值就是该对象的真实类型.
[[class]]: 一个内部属性, 字符串值, 表示对象的类型. 只有 toString 这一个方法可以拿到.
而在 es5 中, toString 获取 [[class]] 值时需要经过这几个比较特殊的步骤:
总结:
调用 toString 时会将 this 对象的 [[class]] 属性值拿到, 而这个属性值就是该对象的真实类型.
又因为 call 能够显示的修改 this 指针的对象, 所以用 call 将 Object 内部的 this 对象指向我们要检测的变量自身.
从而再通过 toString 拿到变量的 [[class]] 值.
方案三: 原型 prototype + isPrototypeOf()方法
Array.prototype.isPrototypeOf(variable)
isPrototypeOf() 函数: 用于指示对象是否存在于一个对象的原型链中. 如果存在返回 true, 反之返回 false. 该方法属 Object 对象, 由于所有的对象都继承了 Object 的对象实例, 因此几乎所有的实例对象都可以使用该方法.
所以在上边代码公式中, 如果 variable 的原型链中存在 Array 对象, 就会返回 true, 也就说明 variable 是数组类型.
isPrototypeOf 的字面意思也就是 a 是不是 b 的原型.
看上图就知道了, Array 就是变量 m 的原型. 所以用这个方法就能判断出来.
对比一个类型为 "纯"Object 的变量打印出来的信息:
就更加一目了然为什么用这个方法就可以判断出来了吧!
方案四: 构造函数 constructor
variable.constructor.toString().indexOf("Array") !== -1
这个一图胜千言:
对比变量 a 的打印信息, 可以看出来, 一个数组类型的实例, 其原型__proto__.constructor 右边是 Array 关键字.
所以我们可以用这个关键点拿到也给字符串:
然后用方案二的原理差不多的, 我们查找字符串中 Array 关键字的位置是否等于 - 1. 即能得出变量是否为数组类型得了.
方案五: 数组方法 isArray()
Array.isArray(variable);
思路:
JS 的一个方法, 专门用来测试对象是否是 Array 类型
在方案一, 二, 三的基础上, 可以总结整理这个 isArray 的内部原理
然后把方案 1234 自己封装成 isArray()函数.(待做)
来源: https://www.cnblogs.com/padding1015/p/9985718.html