You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS类两种属性赋值语法的差异及底层实现疑问

JavaScript类字段语法与构造函数赋值的差异及底层实现

嘿,这个问题问到点子上了——你提到的第二种语法其实是类字段声明语法(ES2022正式纳入标准),它和传统构造函数内的属性赋值不止“动态赋值”这一点区别,咱们来逐一拆解:

一、核心差异点

  • 初始化时机不同
    传统构造函数里的this.prop = prop是在构造函数代码执行到对应行时才赋值;而类字段会在构造函数逻辑执行之前(如果是子类,则在super()调用完成后)就完成初始化。举个例子:

    class Foo {
      constructor() {
        console.log('构造函数执行中');
        this.prop = 1;
      }
    }
    
    class Bar {
      prop = 2;
      constructor() {
        console.log('构造函数执行中');
      }
    }
    
    new Foo(); // 输出:构造函数执行中
    new Bar(); // 输出:构造函数执行中
    // 但Bar的prop在构造函数打印前就已经被赋值为2了
    
  • 支持原生私有字段
    类字段语法原生支持私有实例字段(用#前缀标记),这是传统构造函数赋值无法通过语法层面实现的(只能通过闭包模拟私有性,但写法繁琐且功能有限):

    class Bar {
      #privateProp = '我是私有字段';
      getPrivateProp() {
        return this.#privateProp;
      }
    }
    
    const bar = new Bar();
    console.log(bar.#privateProp); // 报错:私有字段不可外部访问
    console.log(bar.getPrivateProp()); // 输出:我是私有字段
    
  • 子类中的约束更清晰
    在子类中,如果使用构造函数赋值,必须先调用super()才能访问this;而类字段会自动在super()调用完成后初始化,不需要手动处理顺序,避免了忘记调用super()导致的错误。

二、底层实现逻辑

对于普通的公共类字段(比如你例子里的prop = 5),转译工具(如Babel)或者JavaScript引擎的处理逻辑确实和构造函数内赋值非常相似——会把类字段的初始化代码移到构造函数的最前端(子类则在super()之后)。转译后的代码大概是这样:

class bar {
  constructor() {
    this.prop = 5;
  }
}

不过要注意:原生引擎对类字段的实现并非简单“转成构造函数赋值”,尤其是私有字段,引擎会做额外的封装来保证其私有性;但从开发者感知的逻辑层面来看,普通公共类字段的效果和构造函数内提前赋值是一致的。

另外补充个小知识点:类字段语法也支持动态赋值哦!你可以用表达式或者函数返回值来赋值,比如:

class Bar {
  prop = Math.random();
  dynamicProp = this.getDynamicValue();
  
  getDynamicValue() {
    return '动态生成的值';
  }
}

这样就解决了你说的“硬编码”问题~

内容的提问来源于stack exchange,提问作者Willem van der Veen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:06:31