再谈call、apply、bind:轻松掌握this的指向改变
2023-10-03 00:58:17
一、我们为什么需要改变this的指向?
在 JavaScript 中,this 代表当前执行代码的上下文对象。在函数中,this 通常指向该函数所属的对象。然而,在某些情况下,我们可能需要改变 this 的指向,以实现不同的目的。
二、改变this指向的三种方法
1. call() 方法
call() 方法允许我们显式地设置函数的 this 指向。它的语法如下:
function.call(thisArg, arg1, arg2, ...)
其中:
- thisArg :要将 this 指向的对象。
- arg1, arg2, ... :要传递给函数的参数。
例如,我们有一个函数 greet()
,它将向控制台打印出 "Hello, [name]!"。
function greet(name) {
console.log("Hello, " + name + "!");
}
现在,我们想使用 greet()
函数来向控制台打印出 "Hello, World!"。我们可以使用 call() 方法来显式地将 this 指向 window
对象,如下所示:
greet.call(window, "World");
这样,当 greet()
函数被调用时,它的 this 指向将指向 window
对象,并且向控制台打印出 "Hello, World!"。
2. apply() 方法
apply() 方法与 call() 方法类似,但它允许我们以数组的形式传递参数。它的语法如下:
function.apply(thisArg, [args])
其中:
- thisArg :要将 this 指向的对象。
- [args] :要传递给函数的参数数组。
例如,我们有一个函数 sum()
,它将计算并返回两个数字的和。
function sum(num1, num2) {
return num1 + num2;
}
现在,我们想使用 sum()
函数来计算并返回 1 和 2 的和。我们可以使用 apply() 方法来显式地将 this 指向 window
对象,并以数组的形式传递参数,如下所示:
sum.apply(window, [1, 2]);
这样,当 sum()
函数被调用时,它的 this 指向将指向 window
对象,并且将计算并返回 1 和 2 的和。
3. bind() 方法
bind() 方法与 call() 和 apply() 方法不同,它不会立即调用函数,而是返回一个新的函数,该函数的 this 指向已被显式地设置为指定的 thisArg。它的语法如下:
function.bind(thisArg, arg1, arg2, ...)
其中:
- thisArg :要将 this 指向的对象。
- arg1, arg2, ... :要传递给新函数的参数。
例如,我们有一个函数 greet()
,它将向控制台打印出 "Hello, [name]!"。
function greet(name) {
console.log("Hello, " + name + "!");
}
现在,我们想使用 greet()
函数来创建一个新的函数,该函数的 this 指向已被显式地设置为 window
对象。我们可以使用 bind() 方法来创建这个新的函数,如下所示:
var greetWorld = greet.bind(window);
现在,我们可以使用 greetWorld()
函数来向控制台打印出 "Hello, World!"。
greetWorld();
这样,当 greetWorld()
函数被调用时,它的 this 指向将指向 window
对象,并且向控制台打印出 "Hello, World!"。
三、改变this指向的常见场景
改变 this 指向的常见场景包括:
- 函数柯里化: 函数柯里化是指将一个函数的多个参数转换为一个单一参数的过程。通过改变 this 指向,我们可以将函数柯里化。
- 事件监听器: 在 JavaScript 中,事件监听器通常被添加到 DOM 元素上。然而,在某些情况下,我们可能需要将事件监听器添加到其他对象上。通过改变 this 指向,我们可以将事件监听器添加到其他对象上。
- 模拟继承: 在 JavaScript 中,模拟继承是通过改变 this 指向来实现的。通过改变 this 指向,我们可以让一个对象继承另一个对象的属性和方法。
- 模块模式: 模块模式是一种在 JavaScript 中实现私有变量和私有方法的模式。通过改变 this 指向,我们可以将变量和方法私有化。
四、结语
call()、apply() 和 bind() 方法是 JavaScript 中改变 this 指向的三个常用方法。这些方法在许多场景中都有用,包括函数柯里化、事件监听器、模拟继承和模块模式。通过理解和掌握这些方法,我们可以编写出更加灵活和强大的 JavaScript 代码。