call, apply, bind这三个方法都可以改变函数内部this指向。区别是call, apply是立即指向该函数,而bind是返回一个新的函数,用于下次调用。
其中,call和apply的区别是传递函数参数的方式不同,call是一个一个传入,例如call(this, arg1, arg2, arg3)这样。但是apply是通过一个数组传递,比如apply(this, [arg1, arg2, arg3])。
call模拟实现
首先我们实现绑定this功能。
// 比如我们有一个foo函数
function getName() {
return this.name;
}
// 还有一个wechat对象
const wechat = { name: 'fedaily' };
// 我们希望实现
getName.call(wechat); // fedaily
以wechat和getName这个为例,这里的this即getName,context即wechat。
我们将getName赋值给wechat对象的fn熟悉,然后通过wechat对象调用,最后删除这个fn属性。(实际中我们肯定不能用fn这个名字,避免和对象原本重复,我们可以用Symbol实现)
然后我们绑定this的功能就实现。还有传递参数,这个也好办。
Function.prototype.call = function () {
const [ctx, ...args] = arguments;
ctx.fn = this;
ctx.fn(...args);
delete ctx.fn;
}
// 这里其实用了ES6的语法,但是主要为了更好的说明整个实现过程,理解原理就好
</