返回
手动实现call(), apply(), bind()
前端
2023-10-18 03:29:21
为了更好地理解call(), apply()和bind()函数的原理,我们可以尝试手动实现这
三者的用法。
手动实现call(), apply(), bind()
1.回忆
call(), apply(), bind()都是内置的函数,其作用都是为了修改函数执行时的this指向 。当函数被调用时,this指向的是全局作用域 ,但是我们可以使用这三者中的任意一个来修改this指向,使之指向任何我们想要指向的对象。
2.call函数实现
接下来我们开始实现call函数。call函数主要有两个参数,第一个参数是this要指向的对象,第二个参数是参数列表。
Function.prototype.call = function (obj, ...args) {
if (obj == null || obj == undefined) {
obj = window;
}
obj.fn = this;
let result = obj.fn(...args);
delete obj.fn;
return result;
};
3.apply函数实现
apply函数也主要有两个参数,第一个参数是this要指向的对象,第二个参数是参数列表,参数列表必须是以数组的形式书写的。
Function.prototype.apply = function (obj, args) {
if (obj == null || obj == undefined) {
obj = window;
}
obj.fn = this;
let result = obj.fn(args);
delete obj.fn;
return result;
};
4.bind函数实现
bind函数主要有两个参数,第一个参数是this要指向的对象,第二个参数是参数列表,参数列表必须是以数组的形式书写的。
Function.prototype.bind = function (obj, ...args) {
if (obj == null || obj == undefined) {
obj = window;
}
const fn = function () {
this.fn(...args);
};
return fn;
};
5.测试
我们来测试一下我们手写的这三者函数是否实现了。我们来创建一个对象,并通过call、apply和bind这三种方式来调用其内部的函数并打印其内部函数返回的結果。
const obj = {
name: 'John Doe',
age: 30,
greet: function () {
return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
},
};
console.log(obj.greet.call(obj)); // Hello, my name is John Doe and I am 30 years old.
console.log(obj.greet.apply(obj)); // Hello, my name is John Doe and I am 30 years old.
console.log(obj.greet.bind(obj)); // function () {
return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
});
const boundFunction = obj.greet.bind(obj);
console.log(boundFunction()); // Hello, my name is John Doe and I am 30 years old.
6.總結
现在我们已经实现了这三者函数,我们可以看到,这三者函数都是用来修改函数执行时的this指向的。call函数需要两个参数,第一个参数是this要指向的对象,第二个参数是参数列表。apply函数也需要两个参数,第一个参数是this要指向的对象,第二个参数是参数列表,但是参数列表必须是以数组的形式书写的。bind函数也需要两个参数,第一个参数是this要指向的对象,第二个参数是参数列表,参数列表必须是以数组的形式书写的。
这三者函数都是非常有益的,在很多场景下我们都可以使用这三者函数来修改函数执行时的this指向。