chencl1986/Blog

.bind()、.call()、.apply()的区别

Opened this issue · 0 comments

在 JavaScript 中,函数是一等公民,这意味着函数可以像任何其他值一样被传递和操作。这种特性使得 JavaScript 具有强大的表达能力,但同时也带来了一些挑战。其中之一就是如何控制函数的执行上下文,也就是 this 的值。JavaScript 提供了三种方法来改变函数的执行上下文:.bind().call().apply()。这三种方法都是函数对象的方法,可以用来改变函数内部 this 的指向。

.call()

.call() 方法是所有函数对象都拥有的一个方法。它的主要作用是改变函数内部 this 的指向,并立即执行这个函数。.call() 方法接受的第一个参数是你想要指定的 this 的值,后面的参数是你想传递给函数的参数列表。

例如:

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

const person = { name: 'Alice' };

greet.call(person);  // 输出:Hello, my name is Alice

在这个例子中,我们使用 .call() 方法改变了 greet 函数内部 this 的指向,使其指向 person 对象。

.apply()

.apply() 方法的作用和 .call() 方法非常相似,它也是用来改变函数内部 this 的指向,并立即执行这个函数。不同的是,.apply() 方法接受的第二个参数是一个数组,这个数组会被用作函数的参数。

例如:

function greet(greeting, punctuation) {
  console.log(`${greeting}, my name is ${this.name}${punctuation}`);
}

const person = { name: 'Alice' };

greet.apply(person, ['Hello', '!']);  // 输出:Hello, my name is Alice!

在这个例子中,我们使用 .apply() 方法改变了 greet 函数内部 this 的指向,并传递了一个参数数组给 greet 函数。

.bind()

.bind() 方法的作用也是改变函数内部 this 的指向,但与 .call().apply() 不同的是,.bind() 方法并不会立即执行函数,而是返回一个新的函数,这个新的函数的 this 值被绑定到了传递给 .bind() 的第一个参数。

例如:

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

const person = { name: 'Alice' };

const greetAlice = greet.bind(person);

greetAlice();  // 输出:Hello, my name is Alice

在这个例子中,我们使用 .bind() 方法创建了一个新的函数 greetAlice,这个新的函数的 this 值被绑定到了 person 对象。

总结一下,.call().apply().bind() 都可以用来改变函数内部 this 的指向,但它们在如何接受参数和执行函数上有所不同。.call().apply() 会立即执行函数,前者接受一个参数列表,后者接受一个参数数组;.bind() 不会立即执行函数,而是返回一个新的函数,这个新的函数的 this 值被绑定到了传递给 .bind() 的第一个参数。