1. 使用 Object.defineProperty
使用 Object.defineProperty 有两种方式实现只读属性。
方式一:
通过 writable
选项将其设置为只读
const obj = {};
Object.defineProperty(obj, 'readOnlyProp', {
value: 42, // 属性的值
writable: false, // 设置为不可写
enumerable: true, // 可枚举
configurable: false, // 不可配置(不能删除或修改属性描述符)
});
console.log(obj.readOnlyProp); // 42
obj.readOnlyProp = 100; // 静默失败(严格模式下会报错)
console.log(obj.readOnlyProp); // 42
方式二:
通过 get() 和 set() 方法
const obj = {};
Object.defineProperty(obj, 'readOnlyProp', {
get() {
return 42;
}
// 不实现set方法
});
console.log(obj.readOnlyProp); // 42
obj.readOnlyProp = 100; // 静默失败(严格模式下会报错)
console.log(obj.readOnlyProp); // 42
2. 使用 Object.freeze
Object.freeze
可以冻结一个对象,使其所有属性都变为只读。
const obj = {
readOnlyProp: 42,
};
Object.freeze(obj);
console.log(obj.readOnlyProp); // 42
obj.readOnlyProp = 100; // 静默失败(严格模式下会报错)
console.log(obj.readOnlyProp); // 42
3. 使用 getter
通过 getter
可以定义一个只读属性,访问时动态计算值。
const obj = {
get readOnlyProp() {
return 42;
},
};
console.log(obj.readOnlyProp); // 42
obj.readOnlyProp = 100; // 静默失败(严格模式下会报错)
console.log(obj.readOnlyProp); // 42
4. 使用 Proxy
Proxy
可以拦截对对象属性的操作,从而实现只读属性。
const obj = {
readOnlyProp: 42,
};
const readOnlyObj = new Proxy(obj, {
set(target, prop, value) {
if (prop === 'readOnlyProp') {
throw new Error(`Cannot assign to read-only property '${prop}'`);
}
target[prop] = value;
return true;
},
});
console.log(readOnlyObj.readOnlyProp); // 42
readOnlyObj.readOnlyProp = 100; // 抛出错误
总结
-
Object.defineProperty
:适合单个属性的只读设置。 -
Object.freeze
:适合冻结整个对象。 -
getter
:适合动态计算值的只读属性。 -
Proxy
:适合需要拦截属性操作的场景。