在React組件中,一般可經過兩種方式來定義組件的方法:普通函數、箭頭函數;做爲方法存在,那麼二者到底有什麼區別呢?javascript
es6,有一部分是對過去版本的js進行包裝。在使用es6語法的React組件中,要剖析普通函數和箭頭函數定義方法有什麼區別,可經過babel轉換,轉換成咱們熟悉的js語法,看看兩者的原本面目。java
舉個例子:git
class Hello {
greet(){ },
say = () => { },
}
複製代碼
babel轉換後,突出重點,大體以下:es6
function Hello(){
this.say = () => { }
}
function.prototype.greet = function() { }
複製代碼
經過轉義後的代碼,可看到區別:github
普通函數被定義爲類的原型方法bash
經過function建立的原型方法。babel
箭頭函數被定義爲類的實例方法函數
經過箭頭方法建立的實例方法。性能
在es6以前的js語法中,this的指向是一個比較多場景的問題在Js中,在此忽略。咱們今天只講在React組件中這兩種方法的this指向。從上面得出,兩個方法的在類中的的掛載點是不一樣的,然而,這並非致使他們做爲方法,表現差別有所不一樣的緣由,更多的是他們的的建立方式致使this有所區別。ui
箭頭函數定義方法時,this指向的是函數定義時的做用域。看例子:
function A(){
this.num = 2;
this.handleClick = () => { console.log(this.num) };
}
const B = new A();
// 第一種狀況
B.handleClick(); //2
// 第二種狀況
const fn = b.handleClick;
fn(); // 2
複製代碼
而普通函數的this,倒是根據調用它時的對象有所關係。
function A(){
this.num = 2
this.handleClick = function(){console.log(this.num) }
}
const B = new A();
//如下都爲嚴格模式下
B.handleHover(); // 2
const fn = B.handleHover;
fn(); // 報錯,由於在嚴格模式下this爲undefined
複製代碼
不管是原型方法或者是實例方法,致使在調用時,this不一樣,緣由在於他們的建立方式,當使用箭頭函數建立,那麼this將指向函數定義時的做用域;而當使用普通的function建立時,this的指向和函數的調用環境有關,(關於普通函數this的指向有所不瞭解,可經過《你不知道的javascript》熟悉)
因此,不管如何,箭頭函數的this都不會發生改變,this指向的是組件;而普通函數的this隨着調用場景的變化有所變化。
若是咱們在須要將組件的一個方法綁定給一個子元素,爲了保證函數中的this指向的是這個React組件(當函數須要藉助組件的一些狀態和屬性時)。
class Hello extends React.PureComponent {
greet() {console.log(this)}
say = () => { console.log(this)}
render() {
return (
<div>
// 普通函數
<div onClIck={this.greet.bind(this)}>普通函數</div>
<div onClick={(e) => this.greet(e)}></div>
// 箭頭函數
<div onClick={this.say}></div>
</div>
)
}
}
複製代碼
普通函數的傳遞方法視覺上就以爲有點繁瑣,除此以外,更重要的是性能方面。
React的生命週期中,shouldUpdateComponent,當shouldUpdateComponent返回false時,組件將不會從新render,子組件也可避免從新render。在 React 15.3.0 ,Reac可經過React.Purecomponent定義組件,當shouldUpdateComponent進行shallow compare時,避免一些沒必要要的render。而經過普通函數定義的方法,經過bind綁定後,每次父組件發生render時,方法就得從新bind(this),對於子組件而言,它的props、state發生了改變,則必須發生從新渲染。
若是咱們定義的方法不用綁定給子元素,而是被組件本身內部的函數調用,箭頭函數和普通函數均可以用來定義方法。
class DownloadGameBtn extends React.PureComponent {
constructor(props) {
super(props);
this.initInfo();
this.initSize();
}
initInfo() {
console.log(this); // 指向DownloadGameBtn組件
}
initSize = () => {
console.log(this) // 指向DownloadGameBtn組件
}
}
複製代碼
函數做爲React組件的方法時, 箭頭函數和普通函數的區別是什麼?
在工做中遇到的問題,經過各類資料查找,進行總結和概括,感謝各位前輩的分享。這是第一次在一個公共社區發表本身的總結文章,寫的有點蠢蠢的,但願這些能夠幫到和我同樣遇到相似困惑的朋友。而後,你們輕點噴。