js 的 call 与 apply 速度对比

最近在看 underscore 的源码时发现,作者好多都用 call,而用 apply 比较少,比如说这段:

var optimizeCb = function(func, context, argCount) {
  // 如果没有指定 this 指向,则返回原函数
  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 参数
    // 则执行以下 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 呢?
经过网上的搜索发现,call 比 apply 速度快,在 console运行如下代码:

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的结果:

可以发现 call 比 apply 快了10ms 左右,那是什么原因造成这样的呢?
因为 apply 运行前要对作为参数的数组进行一系列检验和深拷贝,而 call 则没有
我们看一下 ECMAScript 是怎么写的:

js 的 call 与 apply 速度对比_第1张图片
js 的 call 与 apply 速度对比_第2张图片

由ECMAScript 标准发现 apply 比 call 的步骤多了好多,这就是 call 比 apply 执行速度快的原因!

你可能感兴趣的:(js 的 call 与 apply 速度对比)