React类组件constructor手动bind与public class field箭头函数方法的区别
两段React类组件代码的差异及问题解答
核心代码差异
两段代码最终实现的功能完全一致,核心区别在于incrementCounter方法的定义方式和this绑定逻辑:
- 第一段采用普通类原型方法+手动bind的写法:
普通写法定义的incrementCounter是挂载在App类的原型对象上的,所有组件实例共享同一个方法副本。由于普通函数的this是运行时动态绑定的,直接作为onClick回调执行时this会丢失(严格模式下指向undefined),所以必须在构造函数中调用this.incrementCounter = this.incrementCounter.bind(this)手动将this固定到当前组件实例。 - 第二段采用公共类字段+箭头函数的写法:
这里的incrementCounter不是原型方法,而是用公共类字段语法直接定义在每个组件实例自身的属性,每个实例会独立创建一份方法副本。
问题解答
1. 是否使用箭头函数定义任意类方法都属于public class field?
不是。公共类字段是ES类的语法特性,和赋值的内容是否为箭头函数无关:只要是在类的顶层作用域(不在构造函数、其他类方法内部)用属性名 = 初始值的形式定义的成员,都属于公共类字段,初始值可以是箭头函数、普通函数、数值、字符串等任意类型。
只是实际开发中我们常利用箭头函数的this特性,用公共类字段语法给类赋值箭头函数来省略手动bind的步骤,才会让很多人误以为箭头函数类方法等于公共类字段。
2. 第二段代码的incrementCounter作为onClick回调时,this为什么能指向组件实例?
这是箭头函数本身的特性决定的:箭头函数没有独立的this绑定,它内部的this会继承自定义时所在外层作用域的this。
公共类字段的初始化时机是类实例创建阶段,和构造函数的执行时机一致,此时箭头函数定义所在的外层作用域的this就是正在初始化的App组件实例,这个this会被永久固定到箭头函数中。后续无论怎么调用这个箭头函数(哪怕作为事件回调被浏览器执行),它的this都不会发生变化,不需要额外手动绑定。
补充说明
两种写法各有优劣:
- 普通原型方法+bind的写法内存占用更低,所有实例共享同一个方法,但是需要手动写bind逻辑,代码更冗余
- 公共类字段+箭头函数的写法更简洁,不用处理this绑定,但是每个实例会单独创建方法副本,少量组件实例的场景下内存开销可以忽略不计,是现在React类组件开发的常用写法
内容的提问来源于stack exchange,提问作者aryan singh
相关产品推荐
相关产品推荐

