要真正禁用所有修改路径,需三步协同:冻结原型本身、锁定构造函数的 prototype 属性、再对关键方法做精细控制。

冻结原型对象后,属性默认已不可修改——但要真正禁用所有修改路径,需三步协同:冻结原型本身、锁定构造函数的 prototype 属性、再对关键方法做精细控制。
冻结原型对象本身
这是最基础的防护。调用 Object.freeze(MyClass.prototype) 后,该原型上所有已有属性自动变为 writable: false 和 configurable: false:
- 赋值覆盖方法会静默失败(严格模式下报
TypeError) -
delete MyClass.prototype.method不生效 -
Object.defineProperty重定义该属性会抛错
⚠️ 必须在类定义完成、任何实例创建前执行,否则已有实例可能已缓存引用或触发代理逻辑。
锁定构造函数的 prototype 属性
仅冻结原型对象不够——攻击者仍可直接替换整个原型:
-
MyClass.prototype = { newMethod() {} }依然可行 - 需进一步锁定构造函数自身的
prototype属性为不可配置
做法是:
Object.defineProperty(MyClass, 'prototype', {
writable: false,
configurable: false,
enumerable: false
});
这样连 MyClass.prototype = ... 赋值都会失败(严格模式下报错)。
对敏感方法单独加固
有些方法需要额外保障,比如防止被意外调用或隐藏枚举行为:
- 用
Object.defineProperty显式设enumerable: false,避免出现在for...in或Object.keys() - 再次确认
writable: false和configurable: false(freeze已设,但显式声明更清晰) - 不推荐删掉方法体,而是保留空实现或抛错,确保调用边界可控
例如:
Object.defineProperty(MyClass.prototype, 'dangerousMethod', {
value() { throw new Error('Forbidden'); },
writable: false,
configurable: false,
enumerable: false
});
注意冻结的局限性
Object.freeze 不递归冻结嵌套对象,也不影响原型链上的继承属性:
- 若原型方法返回一个对象,那个对象本身未被冻结,仍可修改
- 子类原型若未冻结,仍可能被篡改,需对每个相关原型单独处理
- 冻结不可逆,也不能解冻;生产环境慎用,建议只用于明确不变的核心类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











