本文详解JavaScript中delete操作符的行为,重点分析当对象自身属性与原型链属性同名时,delete仅移除自身属性而原型属性依然生效的陷阱。通过实例演示如何正确检测属性存在性,区分in运算符与hasOwnProperty的使用场景,避免逻辑错误。
delete操作符与原型链的交互
在JavaScript中,delete操作符用于删除对象的指定属性。例如,针对一个普通对象,
var obj = {key:5};
执行delete obj.key即可成功移除该对象的key属性,这一过程通常符合预期。然而,当对象的原型(prototype)上也存在同名属性时,行为变得复杂,需要特别注意。
具体代码如下:
var A = function(){};
A.prototype.testMe = true;
var a = new A();
// 覆盖原型属性
a.testMe = true;
if(a.testMe){
// 一些关键代码...
// ....
// 删除这属性
delete a.testMe;
}
// 第二段代码区域 ---------------------------
// 在其它模块中
if(a.testMe){
// 一些关键代码...
// ....
} 上述第二段代码区域是一个常见的陷阱。开发者可能误以为a.testMe已被删除,因此该属性值应为undefined或布尔假。实际上,由于自身属性已被移除,JavaScript引擎会继续在原型链上查找,发现A.prototype.testMe仍为true,因此条件判断依然成立。
这种机制如果不了解,极易导致逻辑漏洞。
属性存在性的正确检测方法
// 补充说明:
若要检测对象是否存在某属性(包括原型链上的属性),可使用:
if ('attrName' in obj)…
若要检测对象自身(非原型链)是否存在某属性,应使用:
obj.hasOwnProperty('attrName')