前言
call apply bind三个方法都是函数调用过程中,手动绑定this值;
call第一个参数为绑定this值的上下文环境,其余参数为要执行函数的入参
apply第一个参数为绑定this值的上下文环境,第二参数为执行函数入参所构建的数组
bind返回一个绑定好this值的函数,第一个参数为绑定this值的上下文环境,其余参数为要执行函数的入参。
// 这里不能使用箭头函数,会出现this指向问题
Function.prototype.myCall = function(ctx, ...rest) {
// 校验ctx入参
ctx = ctx && typeof ctx === 'object' ? ctx : window;
// 使用symbol变量,防止覆盖
const fn = Symbol();
ctx[fn] = this;
// 使用调用对象方法的形式,来修改this指向
const result = ctx[fn](...rest);
// 删除绑定的属性,反正污染ctx
delete ctx[fn];
return result;
}
Function.prototype.myApply = function(ctx, arg) {
//校验入参ctx
ctx = ctx && typeof ctx === 'object' ? ctx : window;
const fn = Symbol();
ctx[fn] = this;
const result = ctx[fn](...arg);
delete ctx[fn];
return result;
}
Function.prototype.myBind = function(ctx, ...rest) {
// 校验入参ctx
ctx = ctx && typeof ctx === 'Object' ? ctx : window;
// 缓存this
const _this = this;
return function(...arg) {
const fn = Symbol();
ctx[fn] = _this;
// 两次入参进行合并,实现函数的柯里化
const result = ctx[fn](...[...arg,...rest]);
delete ctx[fn];
return result;
}
}