bind, call, 和 apply区别

52 阅读2分钟

bind, call, 和 apply 是 JavaScript 中用于改变函数执行上下文(即函数内部的 this 值)的方法。它们的区别如下:

  1. bind 方法:

    • bind 方法用于创建一个新的函数,并将指定的对象作为新函数的执行上下文(this 值)。
    • bind 方法不会立即执行函数,而是返回一个新的函数,可以稍后调用。
    • bind 方法可以接收多个参数,第一个参数是要绑定的执行上下文对象,后续参数是要传递给原函数的参数。
    • 绑定的执行上下文无法被修改。
  2. call 方法:

    • call 方法用于调用函数,并将指定的对象作为函数的执行上下文。
    • call 方法会立即执行函数。
    • call 方法可以接收多个参数,第一个参数是要绑定的执行上下文对象,后续参数是要传递给原函数的参数。
    • 可以通过 call 方法将执行上下文绑定到不同的对象上。
  3. apply 方法:

    • apply 方法与 call 方法类似,也是用于调用函数并改变函数的执行上下文。
    • apply 方法会立即执行函数。
    • apply 方法接收两个参数,第一个参数是要绑定的执行上下文对象,第二个参数是一个数组或类数组对象,其中包含要传递给原函数的参数。
    • 可以通过 apply 方法将执行上下文绑定到不同的对象上。

总结:

  • bind 方法用于创建一个新的函数,并将指定的对象作为执行上下文,不会立即执行函数。
  • call 方法用于立即调用函数,并将指定的对象作为执行上下文。
  • apply 方法用于立即调用函数,并将指定的对象作为执行上下文,参数以数组或类数组对象的形式传递。

这些方法都可以用于在函数执行时动态地改变函数的执行上下文,使函数在不同的对象上执行,并传递不同的参数。

在 JavaScript 中,一旦使用 bind 方法绑定了执行上下文,绑定的执行上下文是无法修改的。这意味着无论如何调用绑定后的函数,其执行上下文都将保持不变。这是 bind 方法与 callapply 方法的一个重要区别。

下面是一些示例来说明这个概念:

function greet() {
  console.log(`Hello, ${this.name}!`);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

const boundGreet = greet.bind(person1);
boundGreet(); // 输出:Hello, Alice!

boundGreet.call(person2); // 输出:Hello, Alice!(执行上下文仍为 person1)

const boundGreet2 = greet.bind(person2);
boundGreet2(); // 输出:Hello, Bob!

在上面的示例中,我们使用 bind 方法将 greet 函数绑定到 person1 对象上,并将返回的绑定函数赋值给 boundGreet。无论我们如何使用 call 方法,绑定的执行上下文始终是 person1,并且无法修改。即使我们再次使用 bind 方法将 greet 函数绑定到 person2 对象上,并将返回的绑定函数赋值给 boundGreet2,它仍然保持与之前绑定的执行上下文不变。

相比之下,使用 callapply 方法可以在每次调用函数时动态地更改执行上下文,如下所示:

function greet() {
  console.log(`Hello, ${this.name}!`);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

greet.call(person1); // 输出:Hello, Alice!
greet.call(person2); // 输出:Hello, Bob!

在上面的示例中,我们使用 call 方法在每次调用 greet 函数时更改执行上下文。第一次调用时,执行上下文为 person1,输出 "Hello, Alice!"。第二次调用时,执行上下文为 person2,输出 "Hello, Bob!"。通过 callapply 方法,我们可以在每次调用函数时灵活地修改执行上下文。