[].slice.call与Array.prototype.slice.call的区别

3

最近我一直在思考。

过去我曾使用过[].slice.call或者[].forEach.call等等... 我认为这样做很棒,因为它可以轻松地将类似数组的东西转换为真正的数组。

然而,后来我开始思考,最好像这样做:Array.prototype.slice.callArray.prototype.forEach.call

我正确地认为这样做有更好的性能吗?原因如下:

  1. [].slice.call会创建一个空数组,然后访问数组的原型,并且需要稍后进行垃圾回收。
  2. Array.prototype.slice.call会直接调用数组原型方法,不会先创建一个空数组,然后遍历原型树。

我有没有漏掉什么?还有,是否有任何我忽略的情况,例如在某些情况下[]Array.prototype更好?


两个标准回答。首先,这不是你的瓶颈。其次,计时一下;我不知道哪个更快。 - user2357112
2
我怀疑有些人喜欢使用[]的主要原因只是因为它更短。 - Barmar
@Barmar 这就是我一开始喜欢它的原因 :) - iLikePrograms
1
我不会使用[].slice.call,而是将Array.prototype.slice保存在本地的变量中。我之所以不使用[].slice.call,是因为它创建了一个从未使用过的对象,即使它很可能不会对性能产生明显影响。 - t.niese
1
Array.prototype.slice.call(arguments-or-whatever) 是一种常见的模式,用于将类数组对象(如函数参数)转换为“真正的”数组。 - laconbass
显示剩余4条评论
1个回答

4

请参考现有基准测试

像我在 jsperf.com 上找到的这个,或者在谷歌上键入"`[].slice performance",类似于这样的查询结果

同一个基准测试的修订稿 15 提供了各种不同的方法,而修订稿 12 对我也很有趣。

使用哪些代码

正如 @Barmar 在评论中指出的那样,[].slice.callArray.prototype.slice.call 更短,因此经常看到前者。

正如 @t.niese 在评论中指出的那样,[].slice.call 会创建一个从未被使用过的对象,尽管它很可能不会有明显的性能影响。

在我看来,如果担心性能问题,我更喜欢在外部范围内使用 bind 创建一个快捷方式,然后使用它,而不是使用 缩写 [].slice.callArray.prototype.slice.call

var slice = Function.prototype.call.bind( Array.prototype.slice );

// and then just

function doSomething( ){
    slice( arguments );
    slice( arguments, 1, -1 );
}

slice( whatever );
slice( whatever, 0, 3 );

// and so on

结论

显然,从基准测试中可以看出性能并不相同。

当性能真的很重要时,请对您的代码进行基准测试,以根据您的需求进行优化。

当性能不足以担忧像这样的小改进时,这是一个与代码风格相关的决定,因此选择个人偏好或遵循您所在项目的代码风格指南。

附注

@Barmar在评论中发布了一个有关过早优化的链接,也非常有趣。


@t.niese 是的,第15个版本有点疯狂。第1个版本足以满足OP的好奇心。 - laconbass
@laconbass 我知道Array.prototype应该更快,并且之前也遇到了jsperf。只是想知道是否有什么明显的事情我忽略了或者不知道。 我想成为一名JavaScript开发人员,所以我想知道所有的东西 :) - iLikePrograms
在这种情况下,请参考@t.niese在问题上的评论。我更新了我的答案,因为我认为这是一个有用的提示,并同意那个说法,另外加入了我个人对这个主题的想法,因为我之前也研究过它。 - laconbass
2
如果一个 var slice = Array.prototype.slice; slice.call(items); 比你的 bind 示例更快/更慢,则主要取决于 JavaScript 引擎本身。但无论如何,如果使用它们中的任何一个导致瓶颈,那么程序/工作流本身很可能存在更大的问题(在将类似数组转换为数组对象之后,数据也用于其他用途,这一步通常比_转换步骤_花费更多的时间)。 - t.niese
1
@laconbass 感谢您的回答 :) 它引发了一些很好的讨论,对于任何其他发现这个问题的人来说都是很棒的! - iLikePrograms
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接