【问题标题】:Why would one use Array.prototype.forEach.call(array, cb) over array.forEach(cb)?为什么要使用 Array.prototype.forEach.call(array, cb) 而不是 array.forEach(cb)?
【发布时间】:2014-12-20 04:46:43
【问题描述】:

我刚刚浏览了今年 ng-europe 会议的一些照片,并注意到一张幻灯片,我认为可能会展示即将到来的 Angular 2 的一些代码。请参见此处:

(来源:https://plus.google.com/u/0/photos/+ThierryLAU/albums/6073085583895256529/6073092865671487010?pid=6073092865671487010&oid=105910465983441810901

我不明白的是:

为什么这段代码的作者使用Array.prototype.forEach.call(array, cb) 而不是较短且(在我看来)等效的版本array.forEach(cb)。我能想象到的唯一原因是对性能的影响。

有人知道另一个区别吗?或者我对性能的猜测是否正确?

【问题讨论】:

  • JS - Why use Prototype?的可能重复
  • 之所以使用[].forEach.call(arr)主要是为了防止类数组对象(arguments对象、DOM节点列表等)因为Array.prototype不在原型链中而抛出错误那些对象。这是一个非常相似的问题,但从另一方提出:stackoverflow.com/questions/1424710/…
  • @澳洲航空。感谢您的回答。但是你为什么把它作为评论而不是答案呢?

标签: javascript angularjs foreach


【解决方案1】:

有很多Array-like objects 看起来像数组,但实际上不是。举个例子:

  • arguments
  • childrenchildNodes 集合
  • document.getElementsByClassNamedocument.querySelectorAll 等方法返回的 NodeList 集合
  • jQuery 集合
  • 甚至是字符串。

许多数组原型方法是通用的,这意味着它们的内部实现不依赖于上下文 this 成为 Array 构造函数的实例。这允许在“看起来”像数组的 other 对象的上下文中调用这些方法。也就是说,看起来像一个数组意味着该对象具有数字键和长度属性。

这是一个无用的示例,说明如何在自定义类数组对象上调用 Array.prototype.join

Array.prototype.join.call({0: 'one', 1: 'two', length: 2}, ' ');

上面将输出字符串"one two"。但是提供的对象显然不是数组。

【讨论】:

  • 但是如果我们将this 传递给window,为什么它仍然有效?它是类似数组的对象吗?例如:Array.prototype.forEach.call( window, function( element, index, array ){ console.log(index, element, array) })
  • @Sotiris 一般来说,您发布的内容在任何页面上都不起作用。我想既然它对你有用,你在页面上用框架测试了这个脚本,对吗?再一次:要成为类数组对象对象必须具有长度属性和数字键:0、1 等。如果文档有框架,则window.length 显示它们的数量和 window[0]、window[1]等引用这些框架/iframe,以便它们出现在文档中。所以在这种情况下window 对象确实变成了类数组,因为它允许通过数字索引访问某些属性并且还具有长度属性。
  • 非常感谢您的洞察力。事实上,它是一些插件的 iframe。在隐身模式下测试它会按预期返回 undefined。
【解决方案2】:

它有点防御 element.attributeselement.children 不是数组。

【讨论】:

    猜你喜欢
    • 2017-06-04
    • 2019-09-19
    • 2016-05-20
    • 2019-09-19
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多