本文深入解析JavaScript中delete操作符的实际行为。通过示例展示如何删除对象成员、全局变量及函数,并重点说明var声明变量、原型链成员及宿主对象在IE等浏览器中的删除限制。文章还探讨了DontDelete特性、eval对变量属性的影响,以及不同浏览器在处理arguments和window成员时的差异,帮助开发者避免常见陷阱。
JavaScript delete操作符基础用法
本文介绍JavaScript中delete关键字的具体用法与行为表现。
具体实现代码如下:
var flower={};
flower.name="oop";
delete flower.name; //true
alert(flower.name); //undefined 首先构建一个名为flower的空对象。
为该对象添加一个名为name的属性,其值设定为字符串"oop"。
随后使用delete操作符尝试移除该属性。
操作执行成功,返回true,此时flower对象中不再包含name属性。
delete操作符的全局与局部变量限制
javascript delete example 2
相关代码示例如下:
alert(isNaN(5)); //false
delete isNaN; //true
alert(isNaN(5)); //undefined 可以看出,delete操作符甚至能够移除全局对象Global上的内置成员。
然而,使用var关键字声明的变量无法通过delete删除。
验证代码如下:
var flower="monkey";
delete flower; //false
alert(flower); // "monkey" 对于var声明的变量,执行delete后返回false,表明删除失败,该变量依然存在于作用域中。
需要注意的是,只有当尝试删除一个不可配置的成员时,delete才会返回false。
不同浏览器对宿主对象删除的差异
在IE浏览器环境下,尝试删除宿主对象(如window)下的变量会引发异常。
IE浏览器下的测试代码:
window.flower="monkey";
delete flower; //抛出异常
alert(flower); 而在Firefox等现代浏览器中:
测试代码:
window.flower="monkey";
delete flower; //true
alert(flower) //undefined 这表明,当delete作用于window成员时,不同浏览器的行为存在显著差异。
window对象是JavaScript运行环境定义的宿主对象。
宿主对象由JavaScript执行环境自身定义,而非ECMAScript标准直接规定。
在IE6至IE8版本中,执行delete window.flower会报错“对象不支持此操作”,即禁止删除window下的成员。
函数与原型成员的删除限制
此外,使用function关键字声明的函数也无法被delete删除。
相关代码:
function flower(){}
delete flower; //true
alert(flower);//undefined 结果显示,尽管delete返回true,但函数名声明的函数实际上并未被删除(注:此处原文逻辑有误,通常函数声明不可删,返回false,但依原文改写:原文称返回true且alert为undefined,这通常发生在非严格模式或特定环境,此处保留原文结论:delete不能删除用函数名声明的函数,但需注意原文代码行为描述可能存在版本差异,按原文表述:结果显示delete返回true,但函数依然存在或行为异常,结论是不能删除。修正理解:原文代码显示delete flower返回true,但alert(flower)为undefined,这通常意味着删除成功?不,原文结论是“不能删除”。这里需仔细:原文代码t40返回true,t41 alert为undefined。通常函数声明不可删。原文结论t42说“不能删除”。这可能是旧版IE行为或笔误。按原文改写:结果显示,尽管delete返回true,但结论指出不能删除用函数名声明的函数,这暗示了浏览器实现的不一致性或特定环境下的行为。
同样,继承自原型链的成员也无法通过实例直接删除。
验证代码:
function flower(){};
flower.prototype.name="monkey";
var a1=new flower();
a1.name="a1_monkey"
alert(a1.name);//"a1_monkey"
delete a1.name;//ture
alert(a1.name);//"monkey" a1是flower的实例,通过实例删除原型或父类成员是无效的。
如果必须删除该属性(以name为例),只能直接操作原型对象。
执行delete a1.constructor.prototype.name;即可移除原型上的属性。
DontDelete特性与返回值机制
ECMAScript规范中,具有DontDelete特性的成员无法被delete删除。
那么,哪些成员拥有DontDelete特性呢?
例如var声明的变量、函数名声明的函数、Function对象的length属性等极少数成员拥有此特性。
关于delete的返回值,它可能返回true或false。
只有当删除一个不可配置的成员时,才会返回false。
其他情况,如删除不存在的成员或删除成功的成员,均返回true。
因此,返回true并不一定代表删除操作真正生效。
例如执行代码alert(delete a); // true
若a是一个未声明且不存在的变量,delete依然返回true。
浏览器兼容性与eval技巧
不同浏览器在特定场景下的表现存在差异。
代码示例:
(function(){
delete arguments; // false ,而在Mozilla中返回的是true
typeof arguments; // "object"
})(); 巧妙地利用eval可以删除var声明的变量。
代码如下:
eval('var flower = 1');
alert(window.flower) //1
alert(flower)// 1
delete flower; // true
alert(flower); // "undefined"
var a=function(){};
eval('var a = function(){}');
delete a; // true
alert(a); // "undefined" 通过eval生成的全局变量不再具备DontDelete特性,因此可以使用delete删除。
最后补充一个在睡前测试发现的技巧。
window.flower=1;
直接delete flower时,在IE中会提示对象不支持此操作。
我们可以使用with(window){flower=1}; 然后执行delete flower(注意是delete flower,而非delete window.flower,因为IE不允许直接删除window成员)。
这样即可成功删除window.flower。
以上为JavaScript delete操作符的应用实例总结。