JavaScript內(nèi)改變this指向

之前我們說(shuō)的都是代碼內(nèi) this 的默認(rèn)指向
今天我們要來(lái)說(shuō)一下如何能改變 this 指向
也就是說(shuō), 你指向哪我不管, 我讓你指向哪, 你就得指向哪

開局在函數(shù)的原型( Function.prototype ) 上有三個(gè)方法
call
apply
bind
既然是在函數(shù)的原型上, 那么只要是函數(shù)就可以調(diào)用這三個(gè)方法,他們?nèi)齻€(gè)的作用就是改變函數(shù)的 this 指向接下來(lái)咱們便開始介紹這三個(gè)方法
準(zhǔn)備一個(gè)函數(shù)
直接調(diào)用函數(shù),按照 this 指向規(guī)則, 該函數(shù)內(nèi)的 this 會(huì)指向 window
1 是傳遞給形參 a 的數(shù)據(jù)
2 是傳遞給形參 b 的數(shù)據(jù)

call 方法
語(yǔ)法: 函數(shù).call( 函數(shù)內(nèi)的 this 指向, 給函數(shù)傳遞的參數(shù), 給函數(shù)傳遞的參數(shù) )
作用: 改變函數(shù)內(nèi)的 this 指向
利用 call 調(diào)用 fn 函數(shù),此時(shí) obj 就是 fn 函數(shù)內(nèi)的 this 指向
1 是傳遞給形參 a 的數(shù)據(jù)
2 是傳遞給形參 b 的數(shù)據(jù)

apply 方法
語(yǔ)法: 函數(shù).apply( 函數(shù)內(nèi)的 this 指向, 數(shù)組類數(shù)據(jù)結(jié)構(gòu) )
作用: 改變函數(shù)內(nèi)的 this 指向
其實(shí) apply 本質(zhì)上和 call 方法沒(méi)有區(qū)別,只是給函數(shù)傳遞參數(shù)的方式不一樣 ,apply 的第二個(gè)參數(shù)是一個(gè)數(shù)組類的數(shù)據(jù)結(jié)構(gòu), 只要是按照索引排列即可
該數(shù)據(jù)結(jié)構(gòu)內(nèi)的每一個(gè)依次是給函數(shù)進(jìn)行形參賦值的數(shù)據(jù)
利用 apply 調(diào)用 fn 函數(shù),此時(shí) arr 就是 fn 函數(shù)內(nèi)的 this 指向,第二個(gè)參數(shù)是一個(gè)數(shù)組
該數(shù)組內(nèi) [0] 數(shù)據(jù)是傳遞給形參 a 的數(shù)據(jù)
該數(shù)組內(nèi) [1] 數(shù)據(jù)是傳遞給形參 b 的數(shù)據(jù)

bind 方法
語(yǔ)法: 函數(shù).bind( 函數(shù)內(nèi)的 this 指向, 給函數(shù)傳遞的參數(shù), 給函數(shù)傳遞的參數(shù) )
作用: 改變函數(shù)內(nèi)的 this 指向
其實(shí) bind 本質(zhì)上和 call 方法沒(méi)有區(qū)別,但是 bind 不會(huì)立即調(diào)用函數(shù),而是返回一個(gè)被鎖定好 this 的新函數(shù)
利用 bind 調(diào)用 fn 函數(shù),此時(shí) obj 就是你想設(shè)置的 fn 函數(shù)內(nèi)的 this 指向
100 是傳遞給形參 a 的數(shù)據(jù)
200 是傳遞給形參 b 的數(shù)據(jù)
但是, 其實(shí)并不會(huì)立即執(zhí)行 fn 函數(shù),而是根據(jù) fn 函數(shù)復(fù)刻了一份一模一樣的函數(shù),新函數(shù)復(fù)制給了 res 變量,res 函數(shù)內(nèi)的 this 被鎖定為了 obj.

通過(guò)瀏覽器查看我們會(huì)發(fā)現(xiàn) fn 函數(shù)并沒(méi)有被調(diào)用,那是因?yàn)?bind 本身就不會(huì)調(diào)用 fn 函數(shù),如果想指向, 需要通過(guò) res 變量調(diào)用

重構(gòu)
上面我們介紹了一下三個(gè)方法的用法,如果你能掌握好, 那么接下來(lái)就來(lái)看看這三個(gè)方法是如何實(shí)現(xiàn)的吧
call 方法重構(gòu)
這樣, 我們的 call 重構(gòu)就完成了
apply 方法重構(gòu)
這個(gè)其實(shí)和 call 方法是差不多的, 只是參數(shù)不一樣了而已,只是根據(jù)調(diào)用方式的不同, 我們接受參數(shù)不在需要 ...args, 直接接收即可
bind 方法重構(gòu)
這個(gè)方法其實(shí)也是非常簡(jiǎn)單,只要利用一下之前重構(gòu)好的 call 或者 apply 方法都可以
此時(shí) bind 的重構(gòu)就完成了,是不是很簡(jiǎn)單呢!