最近在看 underscore 的源碼時(shí)發(fā)現(xiàn),作者好多都用 call烁挟,而用 apply 比較少挥转,比如說這段:
var optimizeCb = function(func, context, argCount) {
// 如果沒有指定 this 指向,則返回原函數(shù)
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1:
return function(value) {
return func.call(context, value);
};
case 2:
return function(value, other) {
return func.call(context, value, other);
};
// 如果有指定 this钥组,但沒有傳入 argCount 參數(shù)
// 則執(zhí)行以下 case
case 3:
return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4:
return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
};
既然 call 和 apply 都能用输硝,那為什么只用 call 而不用 apply 呢?
經(jīng)過網(wǎng)上的搜索發(fā)現(xiàn)程梦,call 比 apply 速度快点把,在 console運(yùn)行如下代碼:
function x(a,b) {}
var a = [1, 2, 3];
console.time("call");
for (var i = 0; i < 1000000; i++) {
x.call(this, 1, 2, 3);
}
console.timeEnd("call");
console.time("apply");
for (var j = 0; j < 1000000; j++) {
x.apply(this, a);
}
console.timeEnd("apply");
console的結(jié)果:
可以發(fā)現(xiàn) call 比 apply 快了10ms 左右,那是什么原因造成這樣的呢屿附?
因?yàn)?apply 運(yùn)行前要對作為參數(shù)的數(shù)組進(jìn)行一系列檢驗(yàn)和深拷貝郎逃,而 call 則沒有
我們看一下 ECMAScript 是怎么寫的:
由ECMAScript 標(biāo)準(zhǔn)發(fā)現(xiàn) apply 比 call 的步驟多了好多,這就是 call 比 apply 執(zhí)行速度快的原因挺份!