當咱們想起箭頭函數時,腦海裏可能會浮現
棒
,酷
,簡潔
,有趣
等形容詞,其實,咱們存在一些更充分的理由
使咱們在聯想起箭頭函數
時不得不想到的react
this
引發的問題箭頭函數不會在函數體內從新定義 this
的值,這使得在回調中的行爲更容易預測,而且避免了 this
在回調中潛存的 bug
瀏覽器
下面咱們來看一個 example
app
咱們指望點擊按鈕,改變按鈕顏色,代碼以下函數
class BrokenButton extends React.Component { render() { return ( <button onClick={this.handleClick} style={this.state}> Set background to red </button> ); } handleClick() { this.setState({ backgroundColor: "red" }); } } render(<BrokenButton />, document.getElementById("root"));
然而,當咱們點擊按鈕時,什麼效果都沒有,爲何會這樣呢性能
其實,不是 handleClick
方法沒有起做用,由於 JavaScript
中壓根沒有方法, JavaScript
中只有函數,而函數中的 this
存在一些規則,正是這些規則,讓上面的 handleClick
中的 this
值變成了 null
優化
你須要清楚明白的是: 你沒法肯定一個方法函數中 this 的指向,由於它的值跟函數的調用方式有關
this
除非,你使用 箭頭函數
,由於箭頭函數中 this
的值是繼承自 外圍做用域
spa
class Button extends React.Component { render() { return ( <button onClick={() => this.setState({ backgroundColor: "red" })} style={this.state} > Set background to red </button> ); } } render(<Button />, document.getElementById("root"));
如今就對了,接下來,咱們繼續調試
瀏覽器對 箭頭函數
的支持大概是 73%
,由於目前,IE
並不支持。但若是你已經意識到這一點,而且你還會代碼轉譯
,這對你來講就不算什麼問題code
你們都發現了,箭頭函數
書寫起來是很是容易的,但書寫忒多的函數,也會形成一些問題
定義函數是昂貴的
瀏覽器每執行一次 =>
,就須要建立一個 新的函數對象
,這實際上是一個比較 昂貴
的操做
固然,若是你不是想構建一個 性能超級無敵宇宙螺旋棒
的組件,渲染一個 很是長
的列表或 很是大
的表格,你也不會發現這是一個 問題
因此,若是你的組件只是在頁面中渲染個幾回,你也 不必忒擔憂
性能這方面的問題
兩個相同的箭頭函數並不相等
爲了讓你們意識到這個問題,接下來,咱們用 ==
比較一下兩個相同的箭頭函數相不相等
const a = x => x, b = x => x; render( <div> <h3> Are <code>a</code> and <code>b</code> equal by <code>==</code>? </h3> <p> {a == b ? "Yes!" : "No :("} </p> </div>, document.getElementById("root") );
若是你在 render
中使用箭頭函數,那麼你在每次調用 render
時都會去建立一個新的函數對象,此時,即便使用 PureComponent
和 shouldComponentUpdate
也起不到優化做用
你能夠在下面實例中看清這一點,其中,<PropChangeCounter />
組件用於打印 props
改變的次數
import PropChangeCounter from "react-armory-prop-change-counter"; class App extends React.Component { constructor(props) { super(props); this.state = { email: "" }; } render() { return ( <div> <input placeholder="Email" value={this.state.email} onChange={e => this.setState({ email: e.target.value })} /> <PropChangeCounter constant={"this doesn't change"} value={this.state.email} onChange={e => this.setState({ email: e.target.value })} /> </div> ); } } render(<App />, document.getElementById("root"));
只定義一次
若是你以爲 性能
對你的組件很重要,那麼你確定會想若是在組件中只定義箭頭函數 一次
該有多好
其中一種實現方式是在 constructor
中使用箭頭函數,固然,對於複雜些的組價來講,這會變的很笨拙
若是你使用了 Babel
或 create-react-app
構建你的應用,你能夠將箭頭函數設置爲 class fields
或 arrow function methods
以下,你能夠將 handleClick
從新定義爲一個 arrow function method
,來修復第一個 example
中的 bug
class Button extends React.Component { render() { return ( <button onClick={this.handleClick} style={this.state}> Set background to red </button> ); } // Note: this syntax is not yet part of JavaScript proper, but is slated // for inclusion in the next version. It should already work with Babel. handleClick = () => { this.setState({ backgroundColor: "red" }); }; }
若是 環境支持
箭頭函數,那麼鼓勵使用
儘可能避免對 React 組件
使用箭頭函數,它會使 調試
變的困難
若是有須要,能夠在 render
中使用箭頭函數
爲 性能
着想,避免在 render
中使用大量函數