1 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊
要理解這個(gè)需要深入理解javascript中函數(shù)內(nèi)置方法call, apply等的運(yùn)作機(jī)制,我們從簡(jiǎn)單的開(kāi)始吧:
1 首先,我們知道call或apply的第一個(gè)參數(shù)是context, 我們來(lái)試驗(yàn)一下:
12345 | function test() { console.log( this .valueOf()); } test.call(); // window / global context test.call(2); // 2 |
這一步很好理解吧?
那么,我們變換一下,把call提出來(lái):
var call = test.call; call === test.call // true call(); //TypeError: object is not a function call(2); //TypeError: object is not a function |
可以看到,call還是那個(gè)call, 但是卻出錯(cuò)了,這告訴我們什么呢? 原來(lái)call或apply內(nèi)部是直接將this做為一個(gè)函數(shù)進(jìn)行調(diào)用(當(dāng)然是對(duì)該函數(shù)進(jìn)行了上下文綁定的)。
2 有了前面的認(rèn)識(shí),理解你這個(gè)問(wèn)題就簡(jiǎn)單多了
首先,func.call.call.call(func2, func3, func4) ,其實(shí)無(wú)論有多少個(gè).call, 最終都等價(jià)于
func.call.call(func2, func3, func4)
即等價(jià)于 Function.prototype.call.call(func2, func3, func4)
我們主要來(lái)分析下 func.call.call(func2, func3, func4)執(zhí)行
a. func.call.call(func2, func3, func4)
為了便于理解,我們做個(gè)變換, 使上面的調(diào)用等價(jià)于如下過(guò)程
12 | var test = func.call; test.call(func2, func3, func4) |
這個(gè)很好理解,就是以func2為context執(zhí)行test函數(shù),并傳入?yún)?shù)func3, func4
b. 執(zhí)行test函數(shù)時(shí)的特殊性
執(zhí)行test函數(shù)時(shí)發(fā)生了一個(gè)很有趣的事,test實(shí)際是func.call函數(shù)也就是Function.prototype.call函數(shù),由第1節(jié)我們知道,這個(gè)函數(shù)的作用是將this(也就是它的context)做為一個(gè)函數(shù)進(jìn)行調(diào)用,由于a中test的context被設(shè)為了func2, 所以執(zhí)行test函數(shù)的結(jié)果實(shí)際是執(zhí)行了func2函數(shù),并且由于call函數(shù)的作用,在調(diào)用func2時(shí),它會(huì)將func3做為func2的context, 并向func2傳入一個(gè)參數(shù)就是func4.
也就是這樣:
1 | func2.call(func3, func4) |
OK, 因此你的兩個(gè)調(diào)用: func.call.call.call(func2,func3,func4), func.call.call(func2,func3, func4) 最終都等價(jià)于
func2.call(func3, func4)
可以看到,func實(shí)際點(diǎn)作用都沒(méi),哦,不,唯一的作用就是引入call函數(shù), 所以有些人也寫成這樣:
1 | Function.call.call(xxx,xx,xx); |
添加回答
舉報(bào)