call func.call(obj,args1,args2); //傳入的是參數(shù)列表
apply func.call(obj,[args1,args2]); //傳入的是數(shù)組參數(shù) 記法:apply是a開頭為array
改變this的指向裸弦,讓bar()函數(shù)的this指向foo對象
var foo={
value: 100
}
function bar(){
console.log(this.value);
}
bar.apply(foo);
等同與將bar函數(shù)作為foo對象屬性進行調用,即為下列方式
var foo={
value: 100
bar: function(){
console.log(this.value);
}
}
因此我們總結模擬思路如下:
1.將執(zhí)行的函數(shù)作為對象屬性
2.執(zhí)行函數(shù)
3.將函數(shù)從對象中刪除
Function.prototype.myCall=function(obj){ //使用該方式在原型鏈上拓展方法作喘,以便所有的函數(shù)都能夠使用.方式調用
var obj=obj||window; //取到傳入的對象(執(zhí)行上下文)理疙,如果不傳參數(shù)默認指向window
var obj.func=this; //給obj對象添加一個func方法,this也就是調用myCall的函數(shù)
var args=[...arguments].slice(1); //取得傳入除了obj的參數(shù)
var result=obj.func(...args); //執(zhí)行函數(shù)
delete obj.func; //刪除函數(shù)
return result;
}
只是和apply傳參上的實現(xiàn)不同
Function.prototype.myApply=function(obj){ //使用該方式在原型鏈上拓展方法泞坦,以便所有的函數(shù)都能夠使用.方式調用
var obj=obj||window; //取到傳入的對象(執(zhí)行上下文)窖贤,如果不傳參數(shù)默認指向window
var obj.func=this; //給obj對象添加一個func方法,this也就是調用myCall的函數(shù)
if(arguments[1]){ //判斷是否傳入數(shù)組參數(shù),如果傳入就要展開數(shù)組
var result=obj.func(...arguments[1])
} else{
var result=obj.func()
}
var result=obj.func(...args); //執(zhí)行函數(shù)
delete obj.func; //刪除函數(shù)
return result;
}