[].slice.call vs Array.prototype.slice.call

[].slice.call vs Array.prototype.slice.call

本文关键字:slice call prototype Array vs      更新时间:2023-09-26

我最近一直在想。

我过去使用过[].slice.call[].forEach.call ....等我认为这样做很好,因为它可以很容易地将数组转换为数组。

然而,然后我开始思考它,它会更好这样做:Array.prototype.slice.callArray.prototype.forEach.call

我认为这有更好的性能是正确的吗,原因如下:

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

我错过了什么吗?也有什么我错过了,比如为什么在某些情况下[]会比Array.prototype更好?

请参考现有基准

就像这个在jsperf.com上我发现输入"'[]。切片性能"

相同基准的修订15也提供了各种各样的方法,而修订12对我来说也很有趣。

使用什么代码

正如@Barmar在评论中指出的,[].slice.call Array.prototype.slice.call,所以前者很常见。

@t。niese在注释中指出,[].slice.call 创建了一个永远不会使用的对象,即使它很可能不会对性能产生明显的影响

IMHO,如果担心性能,我更喜欢在外部作用域上创建bind的快捷方式,然后使用它,而不是快捷方式 Array.prototype.slice.call[].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在评论中发布了一个关于过早优化的链接,也很有趣。