返回

从apply、call和bind看this指向改变的深层原理

前端

在 JavaScript 中,函数的执行上下文决定了函数的 this 指向。默认情况下,函数的 this 指向是全局对象。对于浏览器环境,全局对象是 window。

在某些情况下,我们需要改变函数的 this 指向,使其指向一个特定的对象。这可以通过 apply、call 和 bind 方法来实现。

一、apply 方法

apply 方法接收两个参数:

  1. 第一个参数是需要改变 this 指向的对象。
  2. 第二个参数是一个数组,包含了需要传递给函数的参数。

例如,以下代码将改变函数的 this 指向为对象 person,并传递参数 "John" 给函数:

const person = {
  name: "John"
};

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

greet.apply(person, ["John"]); // 输出 "John"

二、call 方法

call 方法与 apply 方法类似,但是第二个参数不是数组,而是单独的参数。

例如,以下代码将改变函数的 this 指向为对象 person,并传递参数 "John" 给函数:

const person = {
  name: "John"
};

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

greet.call(person, "John"); // 输出 "John"

三、bind 方法

bind 方法与 apply 和 call 方法不同,它不会立即执行函数,而是返回一个新的函数。这个新的函数的 this 指向已经被绑定到第一个参数所指定的对象上。

例如,以下代码将创建一个新的函数,其 this 指向已经被绑定到对象 person。

const person = {
  name: "John"
};

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

const greetPerson = greet.bind(person);

greetPerson(); // 输出 "John"

四、apply、call 和 bind 方法的比较

方法 语法 参数 立即执行 返回值
apply func.apply(thisArg, [args]) thisArg: 要绑定到函数的 this 的对象; args: 要传递给函数的参数数组
call func.call(thisArg, ...args) thisArg: 要绑定到函数的 this 的对象; args: 要传递给函数的参数列表
bind func.bind(thisArg, ...args) thisArg: 要绑定到函数的 this 的对象; args: 要传递给函数的参数列表 一个新的函数,其 this 指向已经被绑定到 thisArg

五、apply、call 和 bind 方法的应用场景

apply、call 和 bind 方法在 JavaScript 中有着广泛的应用场景。以下是一些常见的应用场景:

  • 改变函数的 this 指向: 这是 apply、call 和 bind 方法最常见的应用场景。例如,我们可以使用这些方法来将函数的 this 指向改变为一个特定的对象,从而在不同对象之间共享函数。
  • 柯里化: 柯里化是一种将一个函数分解为多个子函数的技术。我们可以使用 bind 方法来创建柯里化函数,从而使函数更容易使用。
  • 延迟执行: bind 方法可以用来延迟执行一个函数。这对于创建事件处理程序很有用。
  • 函数组合: 函数组合是指将多个函数组合成一个新的函数。我们可以使用 bind 方法来组合函数,从而创建更强大的函数。

六、总结

apply、call 和 bind 方法是 JavaScript 中用于改变函数的 this 指向的常用方法。它们允许开发者将函数中的 this 指向指定为另一个对象,从而在不同对象之间共享函数。