delete仅删除对象自有属性,对继承属性无效;想屏蔽原型属性应实例赋值覆盖;真删原型属性需直接操作原型对象且configurable必须为true。

JavaScript 中原型链机制下属性删除操作的行为逻辑,关键在于区分“自有属性”和“继承属性”,以及 delete 操作符的作用边界。
delete 只影响自有属性,不触碰原型链
delete 操作符仅能移除对象自身的可配置属性,对从原型链上继承来的属性完全无效。即使执行 delete obj.inheritedProp,也不会改变原型上的定义,也不会影响其他实例——因为该属性根本不在 obj 自身上。
- 若属性存在于对象自身(自有),delete 会真正移除它,后续访问将沿原型链向上查找;
- 若属性仅存在于原型上,delete 操作返回 true(看似成功),但实际无任何效果,访问仍能取到原型值;
- 这是很多初学者误以为“删掉了继承属性”的常见误区。
想“屏蔽”原型属性?优先用实例赋值覆盖
多数场景下,你并非真要删除原型上的属性,而是希望某个实例不再使用它。这时更安全、更推荐的做法是:在实例上显式设置同名属性,实现属性遮蔽(shadowing)。
-
obj.prop = undefined或obj.prop = null不是删除,只是覆盖值; -
obj.prop = 'custom'直接遮蔽原型属性,不影响其他实例; - 如需恢复访问原型值,只需
delete obj.prop(删掉实例上的自有属性即可)。
真要删原型上的属性?必须操作原型对象本身
只有直接对原型对象(如 Constructor.prototype 或 Object.getPrototypeOf(obj))使用 delete,才能真正移除该属性。
立即学习“Java免费学习笔记(深入)”;
-
delete MyObj.prototype.foo会让所有基于它的实例失去该属性访问能力; - 该操作会影响所有现有及未来实例,破坏封装性与可预测性;
- 前提是该原型属性的
configurable描述符为 true(默认函数添加的属性通常满足); - 若属性由
Object.defineProperty设为configurable: false,则 delete 失败(严格模式报错,非严格模式返回 false)。
原型链查找与 delete 的协同表现
属性访问遵循“先查自身,再沿 [[Prototype]] 向上找”的规则;delete 则只作用于“查到的第一层”(即自有层)。两者行为天然解耦:
- 删除自有属性后,再次访问同名属性会自动触发原型链查找;
- 原型上被删掉的属性,其下游所有实例同步失效(无缓存、无例外);
- 这种设计让 delete 成为一种“结构性操作”,而非“值级操作”,务必慎用。


















