返回

JS 探究:call 和 apply 谁更胜一筹?

前端

作为 JavaScript 开发者,我们都对 call() 和 apply() 函数并不陌生,它们都是用来改变函数中 this 指向的。call() 和 apply() 函数有一个共同点,就是都会立即执行。但是,当我们被问到它们之间有什么区别时,我们通常会想到一个「传参不同」。但究竟如何传参?又有什么区别呢?

一、基本概念:

  1. call() 函数

    • 语法:functionName.call(thisArg, arg1, arg2, ...)
    • 传参方式:使用逗号分隔的参数列表
    • 用法示例:
      const person = {
        firstName: 'John',
        lastName: 'Doe'
      };
      
      function greet(greeting) {
        console.log(`${greeting} ${this.firstName} ${this.lastName}`);
      }
      
      greet.call(person, 'Hello'); // 输出: Hello John Doe
      
  2. apply() 函数

    • 语法:functionName.apply(thisArg, [args])
    • 传参方式:使用数组来传递参数
    • 用法示例:
      const person = {
        firstName: 'John',
        lastName: 'Doe'
      };
      
      function greet(greeting) {
        console.log(`${greeting} ${this.firstName} ${this.lastName}`);
      }
      
      greet.apply(person, ['Hello']); // 输出: Hello John Doe
      

二、详细比较:

  1. 参数传递:

    • call(): 使用逗号分隔的参数列表
    • apply(): 使用数组来传递参数
  2. 性能比较:

    • 理论上,call() 的性能优于 apply(),因为 apply() 需要将参数转换为数组,而 call() 不需要。
    • 然而,在实际测试中,call()apply() 的性能差异非常小,甚至可以忽略不计。
  3. 使用场景:

    • call()apply() 都可以用来改变函数中 this 的指向。
    • call() 更适合于传入单个参数的情况,而 apply() 更适合于传入多个参数的情况。

三、性能测试:

为了更准确地比较 call()apply() 的性能,我们进行了一个简单的性能测试。我们在 Chrome 浏览器的控制台中创建了一个函数,并分别使用 call()apply() 来调用该函数。然后,我们使用 console.time()console.timeEnd() 来测量函数的执行时间。

const func = function () {
  // do something
};

console.time('call');
func.call(null);
console.timeEnd('call');

console.time('apply');
func.apply(null);
console.timeEnd('apply');

测试结果表明,call()apply() 的性能差异非常小,甚至可以忽略不计。因此,在实际开发中,我们可以根据自己的需要来选择使用 call()apply() 函数。

四、结束语:

通过对 call() 和 apply() 函数的比较,我们发现它们之间的主要区别在于参数的传递方式不同。call() 函数使用逗号分隔的参数列表,而 apply() 函数使用数组来传递参数。在实际开发中,我们可以根据自己的需要来选择使用 call() 或 apply() 函数。