我们都知道call apply bind都可以改变函数调用的this指向。那么它们三者有什么区别,什么时候该用哪个呢?
call、apply与bind的差别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。
call、apply的区别
他们俩之间的差别在于参数的区别,call和aplly的第一个参数都是要改变上下文的对象,而call从第二个参数开始以参数列表的形式展现,apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。
封装apply
Function.prototype.mApply = function (that, argu) {
that = that || window;
var n = this.name; // 函数名
// 修改函数名,以防与对象中其他属性冲突
n += (Math.random() + '').slice(2, 12) + new Date() * 1;
// 将函数赋给对象
that[n] = this;
var res = that[n](...argu);
delete that[n];
return res;
}
封装call
Function.prototype.mCall = function (that, ...argu) {
console.log(this); // 打印了调用mCall的函数
that = that || window;
var n = this.name; // 函数名
// 修改函数名,以防与对象中其他属性冲突
n += (Math.random() + '').slice(2, 12) + new Date() * 1;
that[n] = this;
// 将函数赋给对象
var res = that[n](...argu);
delete that[n];
return res;
}
封装bind
Function.prototype.mBind = function (that, ...arg) {
that = that || window;
var _self = this;
return function () {
return _self.apply(that, arg.concat(...arguments));
}
}
总结
1,当我们使用一个函数需要改变this指向的时候才会用到call apply bind
2,如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)
3,如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])
4,如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)