proxy是实现属性级只读控制的最优方案:通过set陷阱拦截赋值,对只读属性抛错或返回false;支持多属性配置和静默模式,并可配合deleteproperty阻止删除。

要让某个属性真正只读且不可修改,仅靠 Object.freeze 不够——它冻结整个对象,无法单独控制某一个属性;而 Object.defineProperty 又无法监听后续动态添加的属性。ES6 的 Proxy 是最灵活、精准的方案:它能拦截对指定属性的写入操作,并在 set 陷阱中主动拒绝修改。
核心思路:用 set 拦截器拦截赋值,对只读属性抛错或静默忽略
Proxy 不改变原对象,而是通过代理层控制访问行为。只需在 handler.set 中判断属性名,若命中只读字段,就阻止赋值。
- 返回
false(非严格模式下静默失败) - 抛出错误(严格模式或主动校验场景更推荐)
- 不执行
target[prop] = value,确保原始值不被覆盖
实现一个 age 属性只读的示例
下面代码让 age 永远不可修改,其他属性照常可读可写:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
const data = { name: '小明', age: 25, city: '杭州' };
const readOnlyProxy = new Proxy(data, {
set(target, prop, value) {
if (prop === 'age') {
throw new Error('age 属性是只读的,禁止修改');
}
target[prop] = value;
return true;
},
get(target, prop) {
return target[prop];
}
});
readOnlyProxy.name = '小红'; // ✅ 允许
readOnlyProxy.age = 30; // ❌ 报错:age 属性是只读的,禁止修改
console.log(readOnlyProxy.age); // 25(保持原值)
扩展:支持多个只读属性 + 静默保护模式
可以将只读字段列表抽成配置,同时兼容“报错”和“静默忽略”两种策略:
- 定义
readonlyKeys = ['id', 'createdAt', 'version'] - 在
set中检查prop in readonlyKeys - 选择
return false(不报错但赋值无效),适合嵌入式或低侵入场景
注意:Proxy 本身不防删除,需配合 deleteProperty 拦截
如果还希望该属性不能被 delete,需额外定义 deleteProperty 陷阱:
deleteProperty(target, prop) {
if (prop === 'age') {
throw new Error('age 属性不可删除');
}
return delete target[prop];
}
这样,delete readOnlyProxy.age 同样会失败,真正实现“只读 + 不可删”的强约束。










