在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组件的方法时, 箭头函数和普通函数的区别是什么?
在工做中遇到的问题,经过各类资料查找,进行总结和概括,感谢各位前辈的分享。这是第一次在一个公共社区发表本身的总结文章,写的有点蠢蠢的,但愿这些能够帮到和我同样遇到相似困惑的朋友。而后,你们轻点喷。