【D1N910】React 綁定方法為什么會(huì)丟失 this
正常操作,正常分析,大家好,我是 D1n910。

在上周內(nèi)部分享教學(xué) React 的時(shí)候,講到了 React 組件綁定事件

其中傳遞方法的時(shí)候需要用 bind 硬綁定一次 this,然后再傳遞進(jìn)去。像下面這樣:

下面這篇文章
《this 的綁定與丟失問(wèn)題》https://www.jianshu.com/p/6e943792a82a?
系統(tǒng)闡述了 this?使用場(chǎng)景。
?this 的四種綁定方法
一、new綁定
new方式是優(yōu)先級(jí)最高的一種調(diào)用方式,構(gòu)造函數(shù)只是一些使用new操作符時(shí)被調(diào)用的函數(shù)。
只要使用new方式調(diào)用一個(gè)構(gòu)造函數(shù),this一定指向new調(diào)用函數(shù)新創(chuàng)建的對(duì)象。
使用new來(lái)調(diào)用函數(shù)的時(shí)候會(huì)自動(dòng)執(zhí)行下面的操作:
①、創(chuàng)建(或這說(shuō)構(gòu)造)一個(gè)全新的對(duì)象
②、這個(gè)新的對(duì)象會(huì)被執(zhí)行[[Prototype]]連接
③、這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this。
④、如果函數(shù)沒(méi)有返回其他對(duì)象,那么new表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回這個(gè)新對(duì)象
二、顯式綁定
顯式綁定是通過(guò)call()和apply()方法強(qiáng)制制定某些對(duì)象對(duì)函數(shù)進(jìn)行調(diào)用,this則強(qiáng)制指向 調(diào)用函數(shù)的對(duì)象。
可以使用 call(obj, params1,params)、apply(obj, [params1, params2])、bind(obj,?params1,params) 來(lái)進(jìn)行綁定。
他們的不同是?call 、apply 是綁定對(duì)象后立即執(zhí)行函數(shù),而 bind 則是返回綁定對(duì)象后的函數(shù)。
三、隱式綁定
指通過(guò)為對(duì)象添加屬性,該屬性的值即為要調(diào)用的函數(shù),進(jìn)而使用該對(duì)象調(diào)用函數(shù)。

四、默認(rèn)綁定
其他規(guī)則無(wú)法應(yīng)用的時(shí)候,this 會(huì)指向?window,嚴(yán)格模式下,則是指向 undefined。

嚴(yán)格模式下

隱式丟失
在隱式綁定時(shí),使用了?引用賦值?或者 傳參賦值。會(huì)導(dǎo)致丟失。在非嚴(yán)格模式,this 會(huì)綁定在全局對(duì)象 window 上,
1.1、引用賦值
舉個(gè) ??

這里的 fooCopyFn 被賦值的其實(shí)是 foo 本身,相當(dāng)于 var fooCopyFn = foo
demoObj 只是作為中間橋,demoObj.foo 起到的是傳遞的作用。
fooCopyFn 本身無(wú) data,最終打印出來(lái)的,是 window 對(duì)象上的 data

1.2、參數(shù)傳遞
參數(shù)傳遞導(dǎo)致?this 丟失的情況和上面的情況相同,只不過(guò)一般不會(huì)被人發(fā)現(xiàn)

在 fooCopyFn 函數(shù)的參數(shù)傳遞里,隱藏了 fn =?demoObj.foo
總結(jié)下上面的丟失問(wèn)題
(1)這種引用賦值傳遞的函數(shù)(函數(shù)本身也是對(duì)象)很單純,指向的 this 沒(méi)固定(比如就不是原來(lái)的對(duì)象);
(2)函數(shù)運(yùn)行時(shí),指向的 this 為所處的作用域;
在學(xué) React 的事件綁定學(xué)的?bind?方法很好解決這個(gè)問(wèn)題

在這里?bind 方法會(huì)返回一個(gè)新的?this 指向?yàn)?demoObj? 的不純潔?foo 方法。
那么就能夠指向成功了。
React 其實(shí)就是在賦值的時(shí)候,隱式綁定丟失了 this。
拓展內(nèi)容
詭異的箭頭函數(shù)
我們經(jīng)常使用箭頭函數(shù),一方面是因?yàn)樗且环N語(yǔ)法糖,讓我們少寫(xiě)了一些代碼內(nèi)容,一方面則是它能使得內(nèi)部的 this 固定綁定在了所屬父級(jí)作用域上。

比如這里的 this 就被綁定到了 window 上。
我們用 bind 硬綁定修改是不行的。

拓展可以用 call 改變了所屬父級(jí)作用域 this 的指向。

-- END --