Skip to content

如何实现一个只读属性?

最直接的方式是使用 Object.defineProperty(),把属性设置为不可写。

最常见做法

js
const obj = {}

Object.defineProperty(obj, 'name', {
  value: 'foo',
  writable: false,
  enumerable: true,
  configurable: true,
})

这里的关键点是 writable: false

用 getter 也可以实现“只能读”

js
const obj = {
  get name() {
    return 'foo'
  },
}

如果只提供 get,不提供 set,从外部看它也是只读的。

这种方式更适合:

  • 派生值
  • 动态计算值
  • 不希望外部直接写入

Object.freeze 不是“单个只读属性”

js
const obj = {
  name: 'foo',
}

Object.freeze(obj)

它会冻结整个对象,而不只是某一个属性。

所以如果需求是“只把一个字段设成只读”,通常不优先用它。

Proxy 不是这里的首选

理论上可以用 Proxy 拦截写入,但这更适合整对象级别的控制,不是实现单个只读属性的常规方案。

js
const obj = new Proxy(
  { name: 'foo' },
  {
    set(target, prop, value) {
      if (prop === 'name') {
        return false
      }

      target[prop] = value
      return true
    },
  },
)

这种方式可用,但明显比 defineProperty 重。

使用建议

  • 单个只读属性,优先用 Object.defineProperty()
  • 只读且需要动态计算时,用 getter。
  • 需要冻结整个对象时,再考虑 Object.freeze()

基于 MIT 许可发布