JavaScript中class字段与构造函数内定义属性的区别是什么?
两种类属性定义方式的核心差异
两者虽然都能给实例挂载属性,但核心差异可以分为以下4点:
- 执行时机与优先级不同
类字段的赋值逻辑会在构造函数执行前触发,优先级低于构造函数内的赋值。如果两者对同一个属性赋值,构造函数内的赋值会覆盖类字段的初始值,示例如下:
class User { isAdmin = true // 先执行类字段赋值 constructor(name) { this.name = name this.isAdmin = false // 后执行构造内赋值,覆盖之前的值 } } const user = new User('john') console.log(user.isAdmin) // 输出 false
- 对私有属性的支持不同
ES6的私有类属性只能通过类字段语法声明(前缀为#),无法在构造函数内动态创建私有属性,如果没有提前用类字段声明就直接在构造里操作私有属性会直接报错:
class User { // #account = '123' 必须先通过类字段声明才能使用 constructor(name) { this.name = name this.#account = '456' // 未提前声明,直接抛出语法错误 } }
- 代码可维护性不同
类字段会把类的所有实例属性(包括公共、私有)都集中声明在类的顶层位置,其他开发者阅读代码时不需要遍历构造函数的逻辑,就能快速知道这个类的实例会挂载哪些固定属性,代码可读性和可维护性更高。 - 继承场景下的表现差异
子类实例化执行super()的过程中,会先完成父类类字段的赋值,再执行父类构造函数的逻辑,最终才会返回实例给子类操作。如果属性是定义在父类构造内,子类要修改这个属性必须在super()调用之后操作,类字段的初始值则会在super()执行阶段自动完成赋值,不需要额外处理。
内容的提问来源于stack exchange,提问作者Taste of Leaving
相关产品推荐
相关产品推荐

