bind 和 call/apply 同样,都是用来改变上下文 this 指向的,不一样的是,call/apply 是直接使用在函数上,而 bind 绑定 this 后返回一个函数(闭包) call和apply的惟一区别是call的除了第一个参数是绑定上下文,能够传多个参数,apply的第一个参数是绑定上下文,第二个参数是一个数组 calljavascript
Function.prototype.myCall = function(context) {
// 处理第一个参数传null或者undfined,这时将上下文绑定到window对象上
context = context || window;
context._fn = this;
let args = [...arguments].slice(1);
let result = context._fn(...args);
delete context._fn;
return result;
}
复制代码
applyjava
Function.prototype.myApply = function(context) {
context = context || window;
context._fn = this;
let args = [...arguments].slice(1); // 第二个参数是数组
let result = context._fn(...args);
delete context._fn;
return result;
}
复制代码
bind数组
Function.prototype.myBind = function(context) {
let self = this;
let args = [...arguments].slice(1);
return function() {
let newArgs = [...arguments];
return self.apply(context, args.concat(newArgs))
}
}
复制代码
可是做为构造函数试用的时候会出错,构造函数的this绑定在实例上,除此以外,还须要解决原型丢失的问题闭包
Function.prototype.myBind = function(context) {
let self = this;
let args = [...arguments].slice(1);
var bound = function() {
let newArgs = [...arguments];
// 做为构造函数使用
if(this instanceof bound) {
return self.apply(this, args.concat(newArgs))
} else {
return self.apply(context, args.concat(newArgs))
}
}
// 维护原型关系
if(this.prototype) {
bound.prototype = this.prototype;
}
return bound;
}
复制代码