JavaScript中如何使用Object.freeze冻结原型对象防止篡改
时间:2026-08-12 | 作者:深海捕梦者 | 阅读:0Object.freeze不能冻结原型,是因为它只作用于对象自身的属性,不处理[[Prototype]]内部链接或__proto__属性。需分别冻结原型对象并防止原型被替换,才能真正保护原型链。
Object.freeze能锁住的,只有对象本身这一层属性。原型链上的属性,以及原型本身的变化,它都管不到。
也就是说,像原型对象,例如 obj.__proto__ 或 Object.getPrototypeOf(obj),并不会因为它而被直接冻结。原型被重新赋值或继续修改,它同样拦不住。
为什么 Object.freeze 不能冻结原型?
在 Ja vaScript 里,原型链的关联依赖内部属性 [[Prototype]]。
Object.freeze能管住的,只是目标对象自己身上的可枚举和不可枚举属性,方法也算在内。它不会顺着原型链递归冻结,也不会把 __proto__ 或 prototype 这两个属性本身一并锁死。
例如:
const parent = { foo: 'bar' };
const child = { baz: 42 };
Object.setPrototypeOf(child, parent);
Object.freeze(child);
// child 自身属性被冻结
child.baz = 99; // 无效(严格模式报错)
child.newProp = 'test'; // 无效
// 但原型仍可被篡改
parent.foo = 'hacked'; // 成功!child.foo 现在是 'hacked'
Object.setPrototypeOf(child, {}); // 仍可更换原型(freeze 不锁 __proto__)
如何真正保护原型不被篡改?
要做到这一点,需要组合使用多种机制,从不同层面加固。
- 冻结原型对象本身:如果希望原型不可变,就对原型对象调用
Object.freeze(不是子对象) - 防止原型被替换:用
Object.preventExtensions+Object.seal+Object.freeze组合,或更彻底地——使用Object.setPrototypeOf(obj, null)切断原型链后冻结 - 创建不可变构造函数:在类/构造函数定义时冻结其
prototype,并禁用实例的原型修改能力 - 用 class + private fields(#)+ freeze 实例:现代方式,将关键状态封装为私有字段,实例化后冻结自身,原型只保留冻结过的公有方法
实用示例:安全冻结带原型的对象
下面是一种兼顾实例与原型防护的写法:
// 1. 定义并冻结原型对象
const AnimalProto = {
speak() { return `${this.name} makes a sound`; },
getType() { return this.type; }
};
Object.freeze(AnimalProto); // 冻结原型方法和属性
// 2. 创建实例,并冻结自身
function createAnimal(name, type) {
const instance = { name, type };
Object.setPrototypeOf(instance, AnimalProto);
return Object.freeze(instance); // 冻结实例自身
}
const dog = createAnimal('Buddy', 'dog');
console.log(dog.speak()); // "Buddy makes a sound"
dog.name = 'Max'; // 失败
AnimalProto.speak = () => 'hijacked'; // 失败(因 AnimalProto 已 freeze)
Object.setPrototypeOf(dog, null); // 在严格模式下会报错(因 dog 是 frozen,且 setPrototypeOf 需要 extensible)
注意边界情况
- Object.freeze 是浅冻结:若原型属性是对象,其嵌套属性仍可变,需手动深冻或用库
- prototype 仍需单独处理:箭头函数、class 声明的 prototype 默认不可写/不可配置,但依然可被
Object.defineProperty覆盖(除非先 seal/freeze) - 类的静态成员不在 prototype 上:ES6 class 的静态方法/属性不在 prototype 上,需单独冻结
MyClass本身 - 不要冻结全局原型:在模块顶层冻结全局原型(如
Array.prototype)极不推荐——会影响其他代码,且多数环境禁止(如浏览器中会抛出 TypeError)
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- JavaScript正则表达式批量处理HTML标签转义与替换方法
- 时间:2026-08-21
-
- JavaScript函数默认参数的精准JSDoc类型注解方法
- 时间:2026-08-21
-
- JavaScript设置Cookie的SameSite属性防范CSRF攻击
- 时间:2026-08-21
-
- JavaScript中BOM如何打开新的浏览器窗口标签
- 时间:2026-08-20
-
- JavaScript微任务队列在事件循环中的执行机制
- 时间:2026-08-20
-
- JavaScript中网络超时如何用流程控制实现中断
- 时间:2026-08-20
-
- JavaScript防抖函数原理与减少高频事件触发方法
- 时间:2026-08-20
-
- TypeScript六个颠覆认知的核心知识点解析
- 时间:2026-08-20
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
