手写call、apply、bind三剑客,轻松掌控函数指针
2023-12-24 22:54:52
前言
提到改变this
的指向,首先想到的方式就是call
、apply
和bind
。对于每种方式底层是如何实现,大多数人不太清楚,如果你还不清楚他们的用法,请移步call、apply、bind。本文会简单讲解他们的用法,底层实现思路,及模拟实现call
、apply
、bind
。
用法
1. call
call()
方法允许你将一个函数应用到另一个对象的上下文环境中,即改变this
的指向。
function greet(name) {
console.log(`Hello ${name}!`);
}
const person = {
name: 'John'
};
// 调用greet函数,将person对象作为this对象
greet.call(person, 'Jane'); // 输出:Hello Jane!
2. apply
apply()
方法与call()
方法类似,但它接受一个数组作为第二个参数,而不是单独的参数。
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
// 调用sum函数,将numbers数组作为参数数组
const result = sum.apply(null, numbers); // 输出:6
3. bind
bind()
方法创建了一个新的函数,该函数将指定的对象作为其this
值。
function greet(name) {
console.log(`Hello ${name}!`);
}
const person = {
name: 'John'
};
// 创建一个新的函数,该函数将person对象作为this对象
const boundGreet = greet.bind(person);
// 调用boundGreet函数
boundGreet('Jane'); // 输出:Hello Jane!
底层实现思路
1. call
call()
方法的底层实现思路是,它通过修改函数的this
值来达到改变函数调用的上下文环境的目的。
首先,call()
方法将第一个参数(this
对象)作为函数的this
值。然后,它将剩余的参数作为函数的参数来调用函数。
2. apply
apply()
方法的底层实现思路与call()
方法类似,但它接受一个数组作为第二个参数,而不是单独的参数。
首先,apply()
方法将第一个参数(this
对象)作为函数的this
值。然后,它将第二个参数(参数数组)中的元素作为函数的参数来调用函数。
3. bind
bind()
方法的底层实现思路是,它创建一个新的函数,该函数将指定的对象作为其this
值。
首先,bind()
方法将第一个参数(this
对象)作为新函数的this
值。然后,它将剩余的参数作为新函数的参数来创建新的函数。
模拟实现
1. call
Function.prototype.myCall = function (context, ...args) {
if (typeof this !== 'function') {
throw new TypeError('Error: Function.prototype.myCall can only be called on functions');
}
context = context || window;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
};
2. apply
Function.prototype.myApply = function (context, args) {
if (typeof this !== 'function') {
throw new TypeError('Error: Function.prototype.myApply can only be called on functions');
}
context = context || window;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
};
3. bind
Function.prototype.myBind = function (context, ...args) {
if (typeof this !== 'function') {
throw new TypeError('Error: Function.prototype.myBind can only be called on functions');
}
const fn = this;
return function (...bindArgs) {
return fn.apply(context, [...args, ...bindArgs]);
};
};
结语
call
、apply
和bind
是JavaScript中改变函数this
指向的三个重要方法,它们允许你控制函数的this
值,从而实现一些强大的功能。了解call
、apply
和bind
的底层原理,可以帮助你更好地理解JavaScript中的函数指针和高阶函数,并编写出更灵活、可复用的代码。