第2题 有以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() 、 instanceof

163 阅读1分钟

Object.prototype.toString.call()

比较全能,原理大概是获取一个内部属性的值来判断。

Object.prototype.toString.call('An') // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call({name: 'An'}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"

instanceof

instanceof 只能用来判断对象类型,不可以判断原始类型。

所有对象类型 instanceof Object 都是 true。

不能识别iframes。window.frames 属性返回窗口中所有命名的框架。该集合是 Window 对象的数组,每个 Window 对象在窗口中含有一个框架或 。属性 frames.length 存放数组 frames[] 中含有的元素个数。注意,frames[]数组中引用的框架可能还包括框架,它们自己也具有 frames[] 数组。可以使用 frames.length 来获取框架的数量。但是frames彼此之间是相互独立的,所以通过原型链判断是否是数组不可靠。

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

Array.isArray(arr);  // true
arr instanceof Array; // false

Array.isArray()

仅判断是否是array,原理还是利用了Object.prototype.toString.call()。

ES5新增属性,可能不兼容旧版本,判断如果不存在可以如下添加

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