博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React组件方法的两种定义方式
阅读量:6413 次
发布时间:2019-06-23

本文共 2673 字,大约阅读时间需要 8 分钟。

在React组件中,通常可通过两种方式来定义组件的方法:普通函数、箭头函数;作为方法存在,那么两者到底有什么区别呢?

方法挂载点

es6,有一部分是对过去版本的js进行包装。在使用es6语法的React组件中,要剖析普通函数和箭头函数定义方法有什么区别,可通过babel转换,转换成我们熟悉的js语法,看看二者的本来面目。

举个例子:

class Hello {        greet(){ },        say = () => { },    }复制代码

,突出重点,大致如下:

function Hello(){    this.say = () => { }}function.prototype.greet = function() { }复制代码

通过转义后的代码,可看到区别:

  • 普通函数被定义为类的原型方法

    通过function创建的原型方法。

  • 箭头函数被定义为类的实例方法

    通过箭头方法创建的实例方法。

原型方法和实例方法?

  • 属性查找 在查找实例的属性和方法时,首先会在实例的属性、方法中查找,当没有找到时,在循着实例的原型链进行查找,直到查找到对应的属性和和方法,或者最后什么都查不到。这就和性能相关了,查找属性、方法的时间有过不同。
  • 调用 实例方法只能通过实例调用,而原型方法还能通过函数调用,比如:A.prototype.click()。

this指向

在es6之前的js语法中,this的指向是一个比较多场景的问题在Js中,在此忽略。我们今天只讲在React组件中这两种方法的this指向。从上面得出,两个方法的在类中的的挂载点是不同的,然而,这并不是导致他们作为方法,表现差异有所不同的原因,更多的是他们的的创建方式导致this有所区别。

箭头函数定义的方法

箭头函数定义方法时,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(); // 2const 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 (            
// 普通函数
普通函数
this.greet(e)}>
// 箭头函数
) }}复制代码

普通函数的传递方法视觉上就觉得有点繁琐,除此之外,更重要的是性能方面。

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组件    }}复制代码

参考

最后

在工作中遇到的问题,通过各种资料查找,进行总结和归纳,感谢各位前辈的分享。这是第一次在一个公共社区发表自己的总结文章,写的有点蠢蠢的,希望这些可以帮到和我一样遇到类似困惑的朋友。然后,大家轻点喷。

转载于:https://juejin.im/post/5c0515696fb9a049df23d304

你可能感兴趣的文章
Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet 3.0+JSP 2.2深入剖析与实例应用
查看>>
topcoder srm 680 div1 -3
查看>>
具体数学第二版第四章习题(1)
查看>>
高效前端优化工具--Fiddler入门教程
查看>>
【翻译】我钟爱的HTML5和CSS3在线工具
查看>>
Java多线程学习(吐血超详细总结)
查看>>
css3 变形
查看>>
Win7 64bit 安装Mysql5 出错 无法启动服务。
查看>>
嵌入式 H264参数语法文档: SPS、PPS、IDR以及NALU编码规律
查看>>
初识Opserver,StackExchange的监控解决方案
查看>>
给大家讲解一下JavaScript与后台Java天衣无缝相结合
查看>>
探索HTML5之本地文件系统API - File System API
查看>>
javascript有用代码块(1)
查看>>
libevent 笔记
查看>>
PHP实现人人OAuth登录和API调用
查看>>
redis源码笔记 - initServer
查看>>
FindBugs工具常见问题
查看>>
ECSHOP报错误Deprecated: preg_replace(): The /e modifier is depr
查看>>
【iOS】iOS之Button segue弹出popOver消除(dismiss)问题
查看>>
java多线程系列5-死锁与线程间通信
查看>>