前端面试| 数组的判断

229 阅读2分钟

一、判断数组

首先注意:使用typeof不能判断出变量的类型是数组。

console.log(typeof({})) //object
console.log(typeof([])) //object
console.log(typeof(null)) //object

1.从原型入手

用法:Array.prototype.isPrototypeOf(arr)
Array构造函数的原型上,有一个isPrototypeOf()方法用于测试一个对象是否存在于另一个对象的原型链上

Array.prototype.isPrototypeOf([]) // true
Array.prototype.isPrototypeOf({}) // false

2. 从构造函数入手

用法: arr.constructor === Array

let arr = []
console.log(arr.constructor === Array) //true

let arr2 = {}
console.log(arr2.constructor === Array) // false

3. 跨原型链调用toString()

用法:Object.prototype.toString.call(arr) === '[object Array]'

每一个继承Object的对象都有toString方法,如果toString方法没有重写的话,会返回 [Object type],其中type为对象的类型。但当除了Object类型的对象外,其他类型直接使用toString方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。

let arr = [];
console.log(Object.prototype.toString.call(arr) === '[object Array]'); 
// true

这种方法对于所有基本的数据类型都能进行判断,即使是nullundefined

Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"

4.Object.getPrototypeOf

用法:Object.getPrototypeOf(arr) === Array.prototype

该方法返回指定对象的原型,所以只要和Array的原型比较即可。

let arr = [];
console.log(Object.getPrototypeOf(arr) === Array.prototype); 
// true

5.instanceof

用法:arr instanceof Array

instanceof的内部机制是通过判断对象的原型链中是不是能找到类型的prototype

使用instanceof判断一个对象是否为数组,instanceof会判断这个对象的原型链上是否会找到对应的Array的原型,找到返回true,否则返回false

let arr = [];
console.log(arr instanceof Array); // true

instanceof只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object都是true

let arr = []
console.log(arr instanceof Object) //true

instanceof 会有一个问题,它的问题在于假定只有一个全局执行的环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有不同的构造函数。

6. Array.isArray

用法:Array.isArray(arr)
ES5中新增了Array.isArray方法,IE8及以下不支持

let arr = [];
console.log(Array.isArray(arr)); // true

假如不存在 Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}