最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JavaScript 中怎样批量将对象所有属性设为只读
时间:2026-07-09 13:45:46 编辑:袖梨 来源:一聚教程网
Object.freeze()可将对象自身属性设为只读,但不递归冻结嵌套对象;深层冻结需手动递归实现;替代方案可用Object.defineProperty批量设置属性描述符;存在无法冻结Proxy、Map等内置类型及不可枚举symbol属性等限制。
可以通过 Object.freeze() 快速将对象所有自有属性设为只读(不可修改、不可添加、不可删除),但需注意它只作用于对象**自身属性**,不递归冻结嵌套对象。
基础用法:冻结顶层对象
Object.freeze() 是最直接的方式,适用于简单扁平对象:
- 调用后,属性的
writable、configurable、enumerable描述符均被锁定 - 尝试修改属性值、添加新属性或删除属性会静默失败(非严格模式)或抛出错误(严格模式)
- 仅冻结对象自身的属性,原型链上的属性不受影响
示例:
const obj = { a: 1, b: 2 };Object.freeze(obj);obj.a = 99; // 无效(静默)obj.c = 3; // 无效(静默)delete obj.b; // 无效(静默)console.log(obj); // { a: 1, b: 2 }
深层冻结:递归冻结嵌套对象
若对象含嵌套对象(如数组、子对象),需手动递归处理:
立即学习“Java免费学习笔记(深入)”;
- 先检查值是否为普通对象或数组(排除 null、基本类型、Date、RegExp 等)
- 对每个可遍历的自有属性值递归调用冻结函数
- 最后再冻结当前对象自身
简易实现:
function deepFreeze(obj) { if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) { Object.getOwnPropertyNames(obj).forEach(prop => { if (obj[prop] !== null && typeof obj[prop] === 'object') { deepFreeze(obj[prop]); } }); Object.freeze(obj); } return obj;}
使用:deepFreeze({ a: 1, nested: { x: 2 } }) → nested.x 也无法修改。
替代方案:使用 Object.defineProperty 批量设置
若需更精细控制(例如只设 writable: false,但保留 configurable: true),可用 Object.defineProperty 配合 Object.keys():
- 遍历所有自有可枚举属性
- 逐个将其描述符设为
{ writable: false, configurable: false }(等效于 freeze 的效果) - 注意:此方式不自动处理不可枚举属性,需用
Object.getOwnPropertyNames()覆盖
示例:
function makeAllReadOnly(obj) { Object.getOwnPropertyNames(obj).forEach(key => { Object.defineProperty(obj, key, { writable: false, configurable: false, enumerable: true // 保持原有枚举性 }); }); return obj;}
注意事项与限制
Object.freeze() 和类似操作有明确边界:
- 不能冻结 symbol 属性以外的不可枚举属性(但
getOwnPropertyNames可覆盖) - 无法冻结 Proxy、Map、Set 等内置集合类的内部状态,只能冻结其引用
- 冻结后仍可读取属性、调用方法;方法内部若修改 this 或外部变量,不受限制
- ES6 模块默认导出对象常配合
freeze使用,确保 API 稳定
不复杂但容易忽略。
相关文章
- 蚂蚁庄园今日答案(每日更新)2026年1月16日 07-17
- 蚂蚁庄园今日正确答案1月16日 07-17
- 死亡搁浅2全部34个武器的解锁方法条件是什么 07-17
- 星塔旅人全部角色特殊回忆触发条件方式合集 07-17
- Palia帕利亚1.12至1.18村民需求物品清单大全 07-17
- 舒舒服服小岛时光全部魔法种子分布详情图 07-17