返回

谈this、call()、apply()、bind()的那些事

前端

在 JavaScript 中,函数的作用域和执行上下文的概念对于理解代码是如何工作的非常重要。this是指向正在执行代码的对象,它可以是全局对象、函数对象或其他对象。

函数的执行上下文由三个部分组成:

  • 函数的激活对象:该对象存储函数的参数和局部变量。
  • 函数的变量环境:该对象存储函数的父作用域中的变量。
  • 函数的this值:该值是指向正在执行代码的对象。

当函数被调用时,一个新的执行上下文被创建,this值被设置为调用函数的对象。如果函数不是作为对象的方法被调用,那么this值被设置为全局对象。

function sayName() {
  console.log(this.name);
}

const person = {
  name: 'John',
  sayName: sayName
};

person.sayName(); // John

在上面的示例中,sayName()函数被作为person对象的属性调用,因此this值被设置为person对象。因此,当sayName()函数被调用时,它将输出"John"。

如果函数不是作为对象的方法被调用,那么this值被设置为全局对象。

function sayName() {
  console.log(this.name);
}

sayName(); // undefined

在上面的示例中,sayName()函数不是作为对象的方法被调用,因此this值被设置为全局对象。因此,当sayName()函数被调用时,它将输出"undefined"。

call()、apply()和bind()方法可以用来改变函数的this值。

  • call()方法接受两个参数:第一个参数是要改变this值的对象,第二个参数是要调用的函数的参数列表。
function sayName() {
  console.log(this.name);
}

const person = {
  name: 'John'
};

sayName.call(person); // John

在上面的示例中,call()方法被用来改变sayName()函数的this值,将其设置为person对象。因此,当sayName()函数被调用时,它将输出"John"。

  • apply()方法与call()方法类似,但它接受一个参数数组而不是参数列表。
function sayName() {
  console.log(this.name);
}

const person = {
  name: 'John'
};

const args = ['John'];

sayName.apply(person, args); // John

在上面的示例中,apply()方法被用来改变sayName()函数的this值,将其设置为person对象。并且,将args数组作为参数列表传递给sayName()函数。因此,当sayName()函数被调用时,它将输出"John"。

  • bind()方法创建了一个新的函数,该函数的this值被绑定到指定的对象。
function sayName() {
  console.log(this.name);
}

const person = {
  name: 'John'
};

const boundSayName = sayName.bind(person);

boundSayName(); // John

在上面的示例中,bind()方法被用来创建了一个新的函数boundSayName,该函数的this值被绑定到person对象。因此,当boundSayName()函数被调用时,它将输出"John"。

call()、apply()和bind()方法非常有用,可以用来改变函数的this值,从而实现一些特殊的功能。