???call方法
??首先要了解call方法,在特定的作用域中調(diào)用函數(shù)期揪,等于設(shè)置函數(shù)體內(nèi)this對象的值掉奄,以擴(kuò)充函數(shù)賴以運(yùn)行的作用域。一般來說横侦,this總是指向調(diào)用某個方法的對象挥萌,但是使用call()和apply()方法時,就會改變this的指向枉侧。call方法接收兩個參數(shù)引瀑,一個是函數(shù)運(yùn)行的作用域(this),另一個是函數(shù)傳入的參數(shù)
var obj = {
name:'aaa',
age:18,
say:function(a, b, c) {
console.log(this.name, a, b, c);
}
}
var obj2 = {
name:'bbb',
}
Function.prototype.myCall(that, ...argu) {
that = that || window; //如果沒有傳默認(rèn)window
var fn = this; //say函數(shù)
var fnName = this.name + new Date() * 1; //保證say函數(shù)的唯一性
that[fnName] = fn; //在that對象上添加一個函數(shù)
that[fnName](...argu); //執(zhí)行函數(shù)
delete that[fnName]; //用完就刪除
}
obj.say.myCall(obj2, 1, 2, 3);
???apply方法
var obj = {
name:'aaa',
age:18,
say:function(a, b, c) {
console.log(this.name, a, b, c);
}
}
var obj2 = {
name:'bbb',
}
Function.prototype.myApply(that, argu) {
that = that || window; //如果沒有傳默認(rèn)window
var fn = this; //say函數(shù)
var fnName = this.name + new Date() * 1; //保證say函數(shù)的唯一性
that[fnName] = fn; //在that對象上添加一個函數(shù)
that[fnName](...argu); //執(zhí)行函數(shù)
delete that[fnName]; //用完就刪除
}
obj.say.myApply(obj2, [1, 2, 3]);
???bind方法
var obj = {
name:'aaa',
age:18,
say:function(a, b, c) {
console.log(this.name, a, b, c);
}
}
var obj2 = {
name:'bbb',
}
Function.prototype.myBind(that, ...argu) {
var self = this;
return function() {
var newP = argu.concat(...arguments);
self.myApply(that, newP);
}
}
obj.say.myBind(obj2, [1, 2, 3]);