JS类中公有字段与普通字段的区别及两种state定义方式对比
JavaScript类:公有字段 vs 普通实例字段
咱们先明确下概念:这里说的「普通字段」一般指在构造函数里通过this.xxx = 值定义的实例属性,而「公有字段」是ES2022引入的类字段语法,直接在类体(方法之外)定义的xxx = 值。两者的核心区别主要有这几点:
- 定义位置与语法:
- 普通字段必须写在类的方法(通常是构造函数)内部,通过
this绑定到实例上; - 公有字段直接写在类的顶层作用域,不需要包裹在方法里,语法更简洁。
- 普通字段必须写在类的方法(通常是构造函数)内部,通过
- 初始化时机:
- 普通字段的初始化时机完全由构造函数的执行逻辑决定,继承场景下必须在
super()调用之后才能定义; - 公有字段会在
super()调用完成后、构造函数执行之前自动完成初始化,顺序上更早一步。
- 普通字段的初始化时机完全由构造函数的执行逻辑决定,继承场景下必须在
- 声明灵活性:
- 公有字段可以只声明不赋值(比如
myField;),默认值为undefined; - 普通字段必须通过赋值语句才能定义,没法单独声明。
- 公有字段可以只声明不赋值(比如
- 兼容性:
- 普通字段是ES6类的标准语法,几乎所有现代浏览器都支持;
- 公有字段是ES2022的新特性,旧版浏览器(比如IE11)不支持,需要借助Babel等转译工具兼容。
React类组件中两种state定义方式的区别
先提个小细节:你的代码里components应该是大写的Component(React的基础组件类),不过不影响咱们聊核心区别。
先看两种写法:
方式一(构造函数内定义):
class MyClass extends Component { constructor(props) { super(props); this.state = {toto:"toto"} } }
方式二(类公有字段语法):
class MyClass extends Component { state = {toto:"toto"} }
两者的区别主要在这些方面:
- 语法复杂度:方式二省去了构造函数和
super(props)的样板代码,写起来更清爽,现在很多React项目都倾向于这种写法。 - 初始化时机:方式二的
state会在super(props)执行后、构造函数运行前完成初始化;方式一是在构造函数内部、super(props)之后赋值。不过在React的生命周期里,两者最终都会在组件挂载前完成state的初始化,实际效果完全一致(正如你补充的那样)。 - 动态初始化场景:如果state需要依赖props生成,两种方式都能实现:
- 方式一:直接在构造函数里用
props:this.state = {toto: props.toto} - 方式二:可以直接访问
this.props:state = {toto: this.props.toto}(因为类字段初始化时this已经指向实例,props已经被挂载)
- 方式一:直接在构造函数里用
- 额外逻辑的整合:如果你的组件需要在构造函数里做其他事情(比如绑定事件处理函数的上下文:
this.handleClick = this.handleClick.bind(this)),方式一可以把state定义和这些逻辑放在同一个地方;方式二则需要单独处理这些逻辑,或者用箭头函数定义方法来自动绑定上下文。 - 兼容性:方式一的语法兼容性更好,不需要转译就能在旧版浏览器运行;方式二需要Babel支持类字段语法,或者运行在支持ES2022的现代浏览器中。
内容的提问来源于stack exchange,提问作者Ben Grandin
相关产品推荐
相关产品推荐

