call 方法內(nèi)部實(shí)現(xiàn)
- 將這個(gè)函數(shù)設(shè)為指定對(duì)象的屬性
- 傳參后執(zhí)行這個(gè)對(duì)象的方法
- 刪除這個(gè)函數(shù)
- 返回對(duì)象的函數(shù)執(zhí)行結(jié)果
模擬實(shí)現(xiàn)
Function.prototype.call2 = function(opp) {
opp.fn = this;
let args = [...arguments].slice(1);
let result = opp.fn(...args);
delete opp.fn;
return result;
}
apply 方法內(nèi)部實(shí)現(xiàn)
思路類(lèi)似手寫(xiě)call函數(shù)的思路如下,
不同:傳參時(shí)只是第二個(gè)參數(shù)有伸头,且為數(shù)組匾效;不像call,除了第一個(gè)參數(shù)都是需要的參數(shù)
1.將這個(gè)函數(shù)設(shè)為指定對(duì)象的屬性
2.傳參后執(zhí)行這個(gè)對(duì)象的方法
- 刪除這個(gè)函數(shù)
4.返回對(duì)象的函數(shù)執(zhí)行結(jié)果
模擬實(shí)現(xiàn)
Function.prototype.apply2 = function(opp) {
opp.fn = this;
let result;
if(auguments[1]) { //判斷是否有第二個(gè)參數(shù)恤磷,即是否有傳入調(diào)用函數(shù)的參數(shù)
result = opp.fn(…arguments[1])
} else {
result = opp.fn()
}
delete opp.fn;
return result;
}
bind 方法內(nèi)部實(shí)現(xiàn)
- 返回一個(gè)函數(shù)面哼,綁定this,傳遞預(yù)置參數(shù)
- bind返回的函數(shù)可以作為構(gòu)造函數(shù)使用
需注意:通過(guò)new實(shí)例化后 this 指向的是創(chuàng)建出的新對(duì)象扫步,還注意對(duì)原型鏈的影響
模擬實(shí)現(xiàn)
Funcrion.prototype.bind2 = function(opp) {
let fn = this;
let args = [...arguments].slice(1);
let resFn = function() {
fn.apply(this.instanceof fn ? this : opp, args.concat([...arguments]) )
// 檢測(cè) New: 如果當(dāng)前函數(shù)的this指向的是構(gòu)造函數(shù)中的this 則判定為new 操作
}
//為了完成 new操作, 還需要進(jìn)行原型鏈接
// 這里創(chuàng)建了一個(gè)空函數(shù)來(lái)做中間人魔策,承接原函數(shù)(此時(shí)為構(gòu)造函數(shù)了)的原型 給 返回的綁定函數(shù)(resFn))
function Tmp() {}
Tmp.prototype = fn.prototype;
resFn.prototype = new Tmp(); // 修改返回函數(shù)的prototype為 綁定函數(shù)的prototype,這樣的話通過(guò)new創(chuàng)建的實(shí)例就可以繼承這個(gè)綁定函數(shù)(此為構(gòu)造函數(shù))中的屬性河胎;【原型鏈?zhǔn)嚼^承】
//但是直接賦值的話當(dāng)修改返回函數(shù)的prototype時(shí)綁定函數(shù)的prototype也不會(huì)被影響闯袒,所以創(chuàng)建了一個(gè)中間函數(shù)
return resFn;
}