javascript 中的 delete及delete运算符
那么,为什么我们能删除一个对象的属性:
varx={a:1}; deletex.a;//true x.a;//undefined
但却不能删除一个变量:
varx=1; deletex;//false; x;//1
也不能删除一个函数:
functionx(){}; deletex;//false; typeofx;//"function"
注意:delete只有当一个属性无法被删除时才返回false。
每一个属性拥有零至多个如内部属性——*ReadOnly,DontEnum,DontDelete和Internal**。你可以把它们想象为标签——一个属性可能拥有也可能没有某个特殊的内部属性。在今天的讨论中,我们所感兴趣的是DontDelete。
当声明变量和函数时,它们成为了变量对象(Variableobject)——要么是活化对象(在函数代码中),要么是全局对象(在全局代码中)——的属性,这些属性伴随生成了内部属性DontDelete。然而,任何显式/隐式赋值的属性不生成DontDelete。而这就是本质上为什么我们能删除一些属性而不能删除其他的原因。
varGLOBAL_OBJECT=this;
/*'foo'是全局对象的一个属性,它通过变量声明而生成,因此拥有内部属性DontDelete
这就是为什么它不能被删除*/
varfoo=1; deletefoo;//false typeoffoo;//"number" /*'bar
'是全局对象的一个属性,它通过变量声明而生成,因此拥有DontDelete子
这就是为什么它同样不能被删除*/
functionbar(){}; deletebar;//false typeofbar;//"function"
/*'baz'也是全局对象的一个属性,
然而,它通过属性赋值而生成,因此没有DontDelete
这就是为什么它可以被删除*/
GLOBAL_OBJECT.baz="baz"; deleteGLOBAL_OBJECT.baz;//true typeofGLOBAL_OBJECT.baz;//"undefined"
1.5、内建和DontDelete|Build-insandDontDelete
所以这就是所有这一切发生的原因:属性的一个特殊的内部属性控制着该属性是否可以被删除。注意:内建对象的一些属性拥有内部属性DontDelete,因此不能被删除;特殊的arguments变量(如我们所知的,活化对象的属性)拥有DontDelete;任何函数实例的length(返回形参长度)属性也拥有DontDelete:
(function(){ //不能删除'arguments',因为有DontDelete deletearguments;//false; typeofarguments;//"object" //也不能删除函数的length,因为有DontDelete functionf(){}; deletef.length;//false; typeoff.length;//"number" })();
与函数arguments相关联的属性也拥有DontDelete,同样不能被删除
(function(foo,bar){ deletefoo;//false foo;//1 deletebar;//false bar;//"bah" })(1,"bah");
1.6、未声明的变量赋值|Undeclaredassignments
你可能记得,未声明的变量赋值会成为全局对象的属性,除非这一属性在作用域链内的其他地方被找到。而现在我们了解了属性赋值和变量声明的区别——后者生成DontDelete而前者不生成——这也就是为什么未声明的变量赋值可以被删除的原因了。
varGLOBAL_OBJECT=this; /*通过变量声明生成全局对象的属性,拥有DontDelete*/ varfoo=1; /*通过未声明的变量赋值生成全局对象的属性,没有DontDelete*/ bar=2; deletefoo;//false deletebar;//true
注意:内部属性是在属性生成时确定的,之后的赋值过程不会改变已有的属性的内部属性。理解这一区别是重要的。
/*'foo'创建的同时生成DontDelete*/ functionfoo(){}; /*之后的赋值过程不改变已有属性的内部属性,DontDelete仍然存在*/ foo=1; deletefoo;//false; typeoffoo;//"number" /*但赋值一个不存在的属性时,创建了一个没有内部属性的属性,因此没有DontDelete*/ this.bar=1; deletebar;//true; typeofbar;//"undefined"
总结:
变量和函数声明都是活化(Activation)全局(Global)对象的属性。
属性拥有内部属性,其中一个——DontDelete负责确定一个属性是否能够被删除。
全局代码或函数代码中的变量、函数声明都生成拥有DontDelete的属性。
函数参数同样是活化对象的属性,也拥有DontDelete。
删除对象中的属性:delete对象.成员
只能删除自有的成员
只有var声明的全局变量不让delete
使用window.或window[""]增加的全局成员可以delete
ps:Javascript中delete运算符
Delete是Javascript语言中使用频率较低的操作之一,但是有些时候,当我们需要做delete或者清空动作时,就需要delete操作。在这篇文章中,我们将深入探讨如何使用它,以及它是如何工作的。
删除的目的,如你所想,就是要删除某些东西,更具体的说,它会删除对象的属性,如下例:
varBenjamin={ "name":"zuojj", "url":"http://www.zuojj.com" }; deleteBenjamin.name; //Outputs:Object{url:"http://www.zuojj.com"} console.log(Benjamin);
delete运算符将不会删除普通变量,如下例:
varbenjamin="http://www.zuojj.com"; deletebenjamin; //Outputs:"http://www.zuojj.com" console.log(benjamin);
但是,它可以删除“全局变量”,因为它们事实上是全局对象(浏览器中是window)对象的属性。
//Becausevarisn'tused,thisisapropertyofwindow benjamin="zuojj"; deletewindow.benjamin; //ReferenceError:benjaminisnotdefined console.log(benjamin);
delete运算符也有一个返回值,如果删除一个属性成功了,返回true,如果不能删除属性,因为该属性是不可写,将返回false,或者如果在严格模式下会抛出一个错误。
varbenjamin={ "name":"zuojj", "url":"http://www.zuojj.com" }; varnameDeleted=deletebenjamin.name; //Outputs:true console.log(nameDeleted); "usestrict"; varbenjamin_="zuojj"; //Outputs:UncaughtSyntaxError:Deleteofanunqualifiedidentifierinstrictmode. deletebenjamin_;
你可能不知道在什么情况下使用删除运算符。答案是,只要你真的想从对象中删除一个属性。
有的时候,Javascript开发不是删除一个属性,而是把这个属性值设置为null.像下面这样:
varbenjamin={ "name":"zuojj", "url":"http://www.zuojj.com" }; benjamin.name=null;
虽然这有效地切断从原来的值的属性,但该属性本身仍然存在的对象上,你可以看到如下:
//Outputs:Object{name:null,url:"http://www.zuojj.com"} console.log(benjamin);
同时,像in和forin循环运算将不会报告null属性的存在,如果你使用个对象,可能使用这些方法来检查一个对象,你可能想确保你真正删除任何不需要的属性。
最后,你应该记住,删除并没有破坏属性的值,仅仅属性本身,看下面的例子:
varname="zuojj", benjamin={}; benjamin.name=name; deletebenjamin.name; //Outputs:"zuojj" console.log(name);
这里,name和benjamin.name映射到相同的值,真如你所看到的,删除benjamin.name并不会影响name.
以上,就是我对delete运算符的概述,不妥之处,欢迎大家批评指正。