摘要:在語言中,關(guān)于這個關(guān)鍵字的行為一直以來困擾著一代又一代初級開發(fā)者。同時,也充分反應(yīng)了的詭異與靈活。這種情況下,無法自動綁定??偨Y(jié)本文在對比綁定的五種方法的同時,也由遠(yuǎn)及近了解了語言的發(fā)展從的,到的箭頭函數(shù),再到對的改進(jìn)。
在 javascript 語言中,關(guān)于 this 這個關(guān)鍵字的行為一直以來困擾著一代又一代初級開發(fā)者。同時 this,也充分反應(yīng)了 javascript 的詭異與靈活。
但是請別誤會,這篇文章并不會對 this 的特征進(jìn)行全方位講解,因?yàn)檫@些內(nèi)容都可以在各種前端書籍中找到答案。這里,我試圖結(jié)合 React 事件處理函數(shù)關(guān)于 this 綁定的演化史,談一談這個框架設(shè)計(jì)以及 javascript 語言在這一細(xì)節(jié)上的進(jìn)步和完善。同時對比 this 綁定的不同方案,讓大家對 React 、ES next 有一個更清晰的認(rèn)識。
React 處理 this 上下文環(huán)境已經(jīng)有至少五年歷史了。五年期間,方案輩出,我們先來總結(jié)一下。
方法一:React.createClass 自動綁定React 中創(chuàng)建組件的方式已經(jīng)很多,比較古老的諸如 React.createClass 應(yīng)該很多人并不陌生。當(dāng)然,從 React 0.13 開始,可以使用 ES6 Class 代替 React.createClass 了,這應(yīng)該是今后推薦的方法。
但是需要知道,React.createClass 創(chuàng)建的組件,可以自動綁定 this。也就是說,this 這個關(guān)鍵字會自動綁定在組件實(shí)例上面。
// This magically works with React.createClass // because `this` is bound for you. onChange = {this.handleChange}
當(dāng)然很遺憾,對于組件的創(chuàng)建,官方已經(jīng)推薦使用 class 聲明組件或使用 functional 無狀態(tài)組件:
Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. Along with functional components, JavaScript classes are now the preferred way to create components in React.
For your existing createClass components, we recommend that you migrate them to JavaScript classes.
我認(rèn)為,這其實(shí)是 React 框架本身的自我完善和對未來的迎合,是框架和語言發(fā)展的大勢所趨。
方法二:渲染時綁定通過前文,我們知道最傳統(tǒng)的組件創(chuàng)建方式不會有 this 綁定的困擾。接下來,我們假定所有的組件都采取 ES6 classes 方式聲明。這種情況下,this 無法自動綁定。一個常見的解決方案便是:
onChange = {this.handleChange.bind(this)}
這種方法簡明扼要,但是有一個潛在的性能問題:當(dāng)組件每次重新渲染時,都會有一個新的函數(shù)創(chuàng)建。OMG! 這聽上去貌似是一個很大的問題,但是其實(shí)在真正的開發(fā)場景中,由此引發(fā)的性能問題往往不值一提(除非是大型組件消費(fèi)類應(yīng)用或游戲)。
方法三:箭頭函數(shù)綁定這種方法其實(shí)和第二種類似,拜 ES6 箭頭函數(shù)所賜,我們可以隱式綁定 this:
onChange = {e => this.handleChange(e)}
當(dāng)然,也與第二種方法一樣,它同樣存在潛在的性能問題。
下面將要介紹的兩種方法,可以有效規(guī)避不必要的性能消耗,請繼續(xù)閱讀。
constructor 方法是類的默認(rèn)方法,通過new命令生成對象實(shí)例時,自動調(diào)用該方法。
所以我們可以:
constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); }
這種方式往往被推薦為“最佳實(shí)踐”,也是筆者最為常用的方法。
但是就個人習(xí)慣而言,我認(rèn)為與前兩種方法相比,constructor 內(nèi)綁定在可讀性和可維護(hù)性上也許有些欠缺。
同時,我們知道在 constructor 聲明的方法不會存在實(shí)例的原型上,而屬于實(shí)例本身的方法。每個實(shí)例都有同樣一個 handleChange,這本身也是一種重復(fù)和浪費(fèi)。
如果你對 ES next 一直抱有開放的思想,且能夠使用 stage-2 的特性,不妨嘗試一下最后一種方案。
方法五:Class 屬性中使用 = 和箭頭函數(shù)這個方法依賴于 ES next 的新特性,請參考 tc 39: Public Class Fields
handleChange = () => { // call this function from render // and this.whatever in here works fine. };
我們來總結(jié)一下這種方式的優(yōu)點(diǎn):
使用箭頭函數(shù),有效綁定了 this;
沒有第二種方法和第三種方法的潛在性能問題;
避免了方法四的組件實(shí)例重復(fù)問題;
我們可以直接從 ES5 createClass 重構(gòu)得來。
總結(jié)本文在對比 React 綁定 this 的五種方法的同時,也由遠(yuǎn)及近了解了 javascript 語言的發(fā)展:從 ES5 的 bind, 到 ES6 的箭頭函數(shù),再到 ES next 對 class 的改進(jìn)。
React 作為蓬勃發(fā)展的框架也同樣在與時具進(jìn),不斷完善,結(jié)合語言特性的發(fā)展不斷調(diào)整著自身。
最后,我們通過這張圖片來完整回顧:
本文參考了 Cory House 的文章:5 Approaches for Handling this,并在此基礎(chǔ)上進(jìn)行延伸。
我的其他一些關(guān)于 React 文章:
React 組件設(shè)計(jì)和分解思考
做出Uber移動網(wǎng)頁版還不夠 極致性能打造才見真章
解析Twitter前端架構(gòu) 學(xué)習(xí)復(fù)雜場景數(shù)據(jù)設(shè)計(jì)
React Conf 2017 干貨總結(jié)1: React + ES next = ?
React+Redux打造“NEWS EARLY”單頁應(yīng)用 一個項(xiàng)目理解最前沿技術(shù)棧真諦
一個react+redux工程實(shí)例
......
Happy Coding!
PS: 作者Github倉庫,歡迎通過代碼各種形式交流。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83866.html
摘要:右側(cè)展現(xiàn)對應(yīng)產(chǎn)品。我們使用命名為的對象表示過濾條件信息,如下此數(shù)據(jù)需要在組件中進(jìn)行維護(hù)。因?yàn)榻M件的子組件和都將依賴這項(xiàng)數(shù)據(jù)狀態(tài)?;瘧?yīng)用再回到之前的場景,我們設(shè)計(jì)化函數(shù),進(jìn)一步可以簡化為對于的偏應(yīng)用即上面提到的相信大家已經(jīng)理解了這么做的好處。 showImg(https://segmentfault.com/img/remote/1460000014458612?w=1240&h=663...
摘要:右側(cè)展現(xiàn)對應(yīng)產(chǎn)品。我們使用命名為的對象表示過濾條件信息,如下此數(shù)據(jù)需要在組件中進(jìn)行維護(hù)。因?yàn)榻M件的子組件和都將依賴這項(xiàng)數(shù)據(jù)狀態(tài)?;瘧?yīng)用再回到之前的場景,我們設(shè)計(jì)化函數(shù),進(jìn)一步可以簡化為對于的偏應(yīng)用即上面提到的相信大家已經(jīng)理解了這么做的好處。 showImg(https://segmentfault.com/img/remote/1460000014458612?w=1240&h=663...
摘要:在幾天前發(fā)布了新版本,被合入。但是在版本迭代的背后很多有趣的設(shè)計(jì)值得了解。參數(shù)處理這項(xiàng)改動由提出。對透明化處理中的,達(dá)到將包裹起來的目的。對的凍結(jié)認(rèn)為,在中使用和方法是一種反模式。尤其是這樣的新,某些開發(fā)者認(rèn)為將逐漸取代。 showImg(https://segmentfault.com/img/remote/1460000014571148); Redux 在幾天前(2018.04....
閱讀 1191·2023-04-26 02:38
閱讀 1487·2021-11-22 09:34
閱讀 1197·2021-09-26 10:19
閱讀 3187·2019-08-29 17:15
閱讀 3534·2019-08-29 12:27
閱讀 1726·2019-08-26 13:51
閱讀 1871·2019-08-26 13:47
閱讀 1024·2019-08-26 12:20