我正在阅读pallet.js的源代码并遇到过这个问题。
var ret = (function(proto) {
return {
slice: function(arr, opt_begin, opt_end) {
return proto.slice.apply(arr, proto.slice.call(arguments, 1));
},
extend: function(arr, arr2) {
proto.push.apply(arr, arr2);
}
};
})(Array.prototype);
var slice = ret.slice;
var extend = ret.extend;
为什么这有必要?他们为什么不能简单地写下这个:
var slice = function(arr,opt_begin,opt_end) {
return Array.prototype.slice.apply(arr,[opt_begin,opt_end]));
}
var extend = function(arr,arr2) {
return Array.prototype.push.apply(arr,arr2);
}
编辑1:
回答重复的问题。我不认为这是重复的,但这个问题肯定会解决我的问题。所以这是一个优化。但不是每个人都只被评估一次?那么两个函数调用真的有一个显着的改进吗?
另外,如果我们担心性能,为什么我们要调用proto.slice.call(arguments,1)
而不是手工构建两个元素的数组[opt_begin,opt_end]
,切片会更快?
答案 0 :(得分:3)
因为语法太酷了。另外,你可以通过告诉自己它更干燥来合理化它的使用。您没有必要两次输入Array.prototype
。
答案 1 :(得分:0)
我不能确定该代码背后的原始理由是什么(只有作者知道)但我可以看到一些差异:
proto
是一个封闭的局部变量,而Array
则是全局变量。足够智能的Javascript引擎可以优化访问,因为proto
永远不会改变,因此它甚至可以通过值而不是引用来捕获。 proto.slice
可能比Array.prototype.slice
更快,因为需要少查找一次。
将opt_begin
和opt_end
作为undefined
传递与通常不传递它们不同。被调用的函数可以知道参数是否被传递,恰好是undefined
,或者是否传递了它。使用proto.slice.call(arguments, 1)
确保参数仅在实际传递给闭包时才传递给slice
。