确保原型对象不被意外修改,关键是在污染发生前通过冻结内置原型、用Object.defineProperty锁定方法属性、避免替换整个prototype、使用Object.create(null)创建无原型对象四方面实现防护。

确保原型对象不被意外修改,关键在于从属性描述符、对象状态和执行时机三方面入手——不是“防不住”,而是得在污染发生前就锁死。
冻结内置原型对象
这是最直接有效的全局防护。在应用初始化最早阶段(比如 <head> 中第一个 <script>),对常用内置构造函数的 prototype 调用 Object.freeze():
Object.freeze(Object.prototype)Object.freeze(Array.prototype)Object.freeze(String.prototype)Object.freeze(Number.prototype)Object.freeze(Boolean.prototype)
冻结后,任何试图添加、删除或覆盖方法(如 Array.prototype.map = null)的操作都会失败:严格模式下抛 TypeError,非严格模式静默忽略。
定义原型方法时锁定属性特性
不要用简单赋值方式挂载方法,改用 Object.defineProperty 显式设置不可写、不可配置:
-
writable: false→ 阻止通过obj.method = newFn替换 -
configurable: false→ 阻止delete obj.method或二次定义 - 例如:
Object.defineProperty(MyClass.prototype, 'run', { value() {}, writable: false, configurable: false })
避免手动替换整个 prototype 对象
如果必须重设子类原型(如 Child.prototype = Object.create(Parent.prototype)),后续要立即修正 constructor,并考虑对 Child.prototype 本身做轻量级保护:
- 调用
Object.preventExtensions(Child.prototype),防止新增属性 - 或更彻底地
Object.freeze(Child.prototype),但需确保所有方法已正确定义完毕 - 严禁写
Child.prototype = Parent.prototype—— 这会让子类直接共享父类原型,修改即污染
用无原型对象隔离敏感数据
对不需要继承行为的对象(如配置项、映射表、临时合并结果),根本绕过原型链:
- 用
Object.create(null)创建,它没有__proto__,也不继承toString、hasOwnProperty等 - 判断属性存在时,改用
Object.prototype.hasOwnProperty.call(obj, key) - 这类对象天然免疫原型污染,结构干净,行为可预测

















