不能直接删除继承属性,而应避免修改原型、用实例属性遮蔽、冻结原型及从源头防范污染。

不能直接“删除继承属性”来达到安全或隔离效果,因为继承属性本就不属于实例自身。真正该做的是避免修改原型、防止污染,并用更可控的方式覆盖行为。
别用 delete 操作符动原型
虽然 delete MyConstructor.prototype.prop 语法上可行,但它会立即影响所有已有和未来创建的实例,破坏封装性与可预测性。一旦删掉,无法恢复(除非重新赋值),且调试时很难追溯源头。这不是删除属性,是全局副作用操作。
用实例属性遮蔽代替删除
若某个实例需要“忽略”原型上的某个属性,就在该实例上显式设置同名属性:
- obj.myMethod = undefined 或 obj.myMethod = function() {},可覆盖原型方法
- obj.prop = null 或 obj.prop = void 0,让访问返回预期值而非原型值
- 后续可通过 delete obj.prop 移除实例属性,从而恢复对原型属性的访问
冻结原型防止意外修改
对构造函数的 prototype 使用 Object.freeze() 是最有效的防御手段:
立即学习“Java免费学习笔记(深入)”;
- Object.freeze(MyConstructor.prototype) 后,任何添加、删除、重写属性的操作都会静默失败(非严格模式)或抛出错误(严格模式)
- 内置对象如 Array.prototype、Object.prototype 也建议尽早冻结,防范原型污染
- 注意:freeze 只作用于目标对象本身,不递归冻结其原型;如需彻底防护,应逐层冻结原型链
从源头切断污染路径
很多“继承属性被删/被改”的问题,实际源于不受控的数据合并(如 Object.assign、JSON.parse + 用户输入):
- 解析用户数据时,避免直接合并到普通对象,优先使用 Object.create(null) 创建无原型对象
- 对输入字段做白名单过滤,禁用 __proto__、constructor、prototype 等敏感键名
- 使用结构化克隆(structuredClone)或专用深拷贝库替代不安全的 Object.assign


















