主题
如何实现一个只读属性?
最直接的方式是使用 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()。
