【问题标题】:Difference between using Array.isArray and instanceof Array使用 Array.isArray 和 instanceof Array 的区别
【发布时间】:2014-04-12 22:33:36
【问题描述】:

有两种方法可以判断一个数组是数组还是对象。使用 typeof item === "object"; 将为对象和数组返回 true,因为数组对于 javascript 来说相对较新,并且数组是对象的原型(可能措辞错误,请随时纠正我)。所以我知道确定一个数组是否是一个数组的两种方法是:

解决方案 1:

Array.isArray(item);

解决方案 2:

item instanceof Array;

我的问题是:

  1. 这两种解决方案有什么区别?
  2. 这两个中的哪个是首选解决方案?
  3. 哪个处理时间更快?

【问题讨论】:

标签: javascript arrays


【解决方案1】:

1.这两种方案有什么区别?

isArray 是一种 ES5 方法,因此旧版浏览器不支持,但它可以可靠地确定对象是否为数组。

instanceof 仅检查 Array.prototype 是否在对象的 [[Prototype]] 链上。跨帧检查数组时失败,因为用于实例的 Array 构造函数可能与用于测试的构造函数不同。

2.这两个中的哪个是首选方案?

“首选”假设了一些选择标准。一般来说,首选的方法是这样的:

if (Object.prototype.toString.call(obj) == '[object Array]')

适合 ES3 浏览器并跨框架工作。如果只考虑 ES5 浏览器,isArray 可能没问题。

3.哪个处理时间更快?

几乎不相关,因为两者的处理时间都可以忽略不计。更重要的是选择一个可靠的。 Array.isArray 方法可以添加到没有内置它的浏览器中:

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

【讨论】:

  • 三倍等于=== 不是更可靠吗?
  • @vad—不。 Object.prototype.toString 总是返回一个字符串,所以===== 的结果是相同的。
  • 请注意,在 ES6+ 中,一个对象可能会给自己一个自定义的toStringTag,从而导致[object Array],尽管它实际上不是一个数组。我不确定Array.isArray 是否可以使用完全可靠的 polyfill
  • @CertainPerformance——当然,但上面只建议在 Array.isArray 不可用的情况下使用 pollyfill,不包括 ECMAScript 2015(在 ES5 和 4 年后引入isArray) 及更高版本。
  • > "基本上不相关,因为两者的处理时间都可以忽略不计。"这取决于您调用这些方法的程度。在某些情况下,例如游戏性能非常重要。
【解决方案2】:
  1. Array.isArray(item)item instanceof Array 之间的区别

    正如评论中提到的 Felix Kling,instanceof Array 不适用于 iframe。给你一个具体的例子,试试下面的代码:

    var iframeEl = document.createElement('iframe');
    document.body.appendChild(iframeEl);
    iframeArray = window.frames[window.frames.length - 1].Array;
    
    var array1 = new Array(1,1,1,1);
    var array2 = new iframeArray(1,1,1,1);
    
    console.log(array1 instanceof Array);  // true    
    console.log(Array.isArray(array1));  // true
    
    console.log(array2 instanceof Array);  // false    
    console.log(Array.isArray(array2));  // true    
    

    正如您在上面的示例中看到的,当您使用 instanceof Array 时,使用 iframe 中的 Array 构造函数创建的数组(即array2)不会被识别为数组。但是,在使用Array.isArray() 时,它被正确识别为数组。

    如果您有兴趣了解为什么 instanceof Array 不适用于不同的全局变量(即 iframewindow),您可以在 here 上阅读更多相关信息。

  2. 这两个中的哪一个是首选解决方案?

    在大多数情况下instanceof Array 应该足够了。但是,由于 instanceof Array 不能在 iframes/window 上正常工作,Array.isArray() 将是更强大的解决方案。

    请务必检查浏览器兼容性。如果您需要支持 IE 8 或更低版本,Array.isArray() 将不起作用(请参阅Mozilla's doc)。

  3. 哪个处理时间更快?

    根据这个jsperfinstanceof ArrayArray.isArray() 快。这是有道理的,因为Array.isArray() 执行更强大的检查,因此会受到轻微的性能影响。

【讨论】:

  • 刚刚遇到这个问题,想指出在某些浏览器中Array.isArray() 现在明显快于instanceof Array
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2018-08-30
  • 2017-03-12
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
相关资源
最近更新 更多