介绍bind/apply/call
1. bind() 方法
bind() 方法创建一个新的函数,该函数会将其调用时的上下文(this 值)绑定到指定的对象,并可在调用时传入预设参数。
-
作用:改变函数的执行上下文,并返回一个绑定了指定上下文的新函数。
-
语法:
function.bind(thisArg, arg1, arg2, ...) -
参数:
thisArg:要绑定到函数上下文的对象。arg1, arg2, ...:要预设给新函数的参数列表。
-
返回值:一个带有指定上下文和预设参数的新函数。
-
示例:
function greet(name) { console.log(`Hello, ${name}!`); } const person = { name: "John", }; const sayHelloToPerson = greet.bind(person); sayHelloToPerson(); // 输出: Hello, John!
2. call() 方法
call() 方法调用一个函数,并设置函数内部的 this 值为指定的对象,还可以传递一系列参数。
-
作用:改变函数的执行上下文,并立即执行该函数。
-
语法:
function.call(thisArg, arg1, arg2, ...) -
参数:
thisArg:要绑定到函数上下文的对象。arg1, arg2, ...:要传递给函数的参数列表。
-
返回值:函数的返回值(如果有)。
-
示例:
function greet() { console.log(`Hello, ${this.name}!`); } const person = { name: "John", }; greet.call(person); // 输出: Hello, John!
3. apply() 方法
apply() 方法调用一个函数,并设置函数内部的 this 值为指定的对象,还可以传递一个数组作为参数。
-
作用:改变函数的执行上下文,并立即执行该函数。
-
语法:
function.apply(thisArg, [argsArray]) -
参数:
thisArg:要绑定到函数上下文的对象。argsArray:一个包含要传递给函数的参数的数组。
-
返回值:函数的返回值(如果有)。
-
示例:
function greet() { console.log(`Hello, ${this.name}!`); } const person = { name: "John", }; greet.apply(person); // 输出: Hello, John!
这些方法的区别在于它们如何传递参数。bind() 方法创建一个新函数,不会立即执行,而是返回一个绑定了特定上下文和参数的函数。call() 和 apply() 方法直接调用函数并立即执行,但它们之间的区别在于参数的传递方式。call() 方法接受一系列参数,而 apply() 方法接受一个数组作为参数。
手写bind/apply/call
手写 bind() 方法,注意点:
- 返回一个新函数。
- 新函数在调用时的上下文是绑定的对象。
- 可以传递预设参数。
// 自定义 bind() 方法
Function.prototype.myBind = function (thisArg, ...args) {
const originalFunc = this; // 原始函数
return function (...innerArgs) {
return originalFunc.apply(thisArg, [...args, ...innerArgs]);
};
};
// 示例使用
function greet(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: "John",
};
const sayHelloToPerson = greet.myBind(person);
sayHelloToPerson("Alice"); // 输出: Hello, John!
手写实现 apply() 方法,可以遵循以下步骤:
- 将
apply()方法添加到Function.prototype中,以便所有函数都可以调用它。 - 在自定义的
apply()方法内部,将调用上下文设置为指定的对象,并执行该函数。
// 自定义 apply() 方法
Function.prototype.myApply = function (thisArg, argsArray) {
const originalFunc = this; // 原始函数
if (!Array.isArray(argsArray)) {
throw new TypeError("argsArray must be an array");
}
return originalFunc.call(thisArg, ...argsArray);
};
// 示例使用
function greet(name, age) {
console.log(`Hello, ${name}! You are ${age} years old.`);
}
const person = {
name: "John",
};
greet.myApply(person, ["Alice", 25]); // 输出: Hello, John! You are 25 years old.
手写实现 call() 方法,可以按照以下步骤进行:
- 将
call()方法添加到Function.prototype中,以便所有函数都可以调用它。 - 在自定义的
call()方法内部,将调用上下文设置为指定的对象,并执行该函数。
// 自定义 call() 方法
Function.prototype.myCall = function (thisArg, ...args) {
const originalFunc = this; // 原始函数
thisArg = thisArg || window; // 如果没有传递上下文,则默认为全局对象
thisArg.__fn__ = originalFunc; // 在上下文对象中创建一个临时属性来存储原始函数
const result = thisArg.__fn__(...args); // 执行原始函数
delete thisArg.__fn__; // 删除临时属性
return result;
};
// 示例使用
function greet(name) {
console.log(`Hello, ${name}!`);
}
const person = {
name: "John",
};
greet.myCall(person, "Alice"); // 输出: Hello, Alice!