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

如何在JavaScript类中创建不可重分配的final属性?

在JavaScript类中实现类似Java final的属性(无需Getter)

下面提供几种无需getter的方案,实现类实例属性一旦初始化就无法被重新赋值:

方案1:构造函数中用Object.defineProperty定义只读属性

直接在构造函数里完成值的计算,再通过Object.defineProperty把属性标记为不可写、不可配置,彻底阻止后续修改:

import { computeSomeValue } from './your-module.js';

class MyClass {
  constructor() {
    const computedValue = computeSomeValue();
    // 定义只读属性
    Object.defineProperty(this, 'someProperty', {
      value: computedValue,
      writable: false,       // 禁止重新赋值
      configurable: false,   // 禁止删除或修改属性描述符
      enumerable: true       // 允许属性被枚举(可选,按需设置)
    });
  }
}

// 测试示例
const obj = new MyClass();
console.log(obj.someProperty); // 输出计算后的初始值
obj.someProperty = 'new value'; // 严格模式下抛出TypeError,非严格模式静默失败

方案2:类字段初始化后,修改属性描述符

如果习惯用类字段语法初始化,可以先完成值的计算,再在构造函数里把属性改成只读:

import { computeSomeValue } from './your-module.js';

class MyClass {
  // 先计算并初始化属性值
  someProperty = computeSomeValue();

  constructor() {
    // 把已存在的属性设置为只读
    Object.defineProperty(this, 'someProperty', {
      writable: false,
      configurable: false
    });
  }
}

这个方案更简洁,保留了类字段的直观写法,同时实现了只读效果。

方案3:冻结实例(谨慎使用)

如果你的类实例所有属性都不需要修改,可以直接在构造函数里冻结整个实例:

import { computeSomeValue } from './your-module.js';

class MyClass {
  someProperty = computeSomeValue();
  // 其他属性...

  constructor() {
    Object.freeze(this);
  }
}

注意:冻结整个实例后,所有属性都无法修改或删除,适合纯数据类场景。

关键注意点

  • 严格模式:建议开启严格模式(文件顶部加'use strict';),这样修改只读属性会直接抛出错误,方便排查问题,而非严格模式下会静默失败。
  • 不可配置的作用:设置configurable: false后,该属性不仅不能被修改,还无法被删除,也不能再修改它的属性描述符。
  • 枚举性:如果需要属性能被Object.keys()或for...in遍历到,要确保enumerable: true(类字段默认是可枚举的,Object.defineProperty默认是不可枚举的)。

内容的提问来源于stack exchange,提问作者SoluableNonagon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:12:44