JS的delete操作

参考:http://www.cnblogs.com/xboy2012/archive/2012/08/29/jsdelete.html

Javascript的变量  

  实际上Javascript中,变量 等同于 对象属性,这是因为 Javascript 在执行脚本之前会创建一个Global对象,所有的全局变量都是这个

Global对象的属性,执行函数时也会创建一个Activation对象,所有的局部变量都是这个Activation对象的属性。如下例:

var global = 42;
this.global;    // 42, 可以通过this来访问Global对象

this.global2 = 12;
global2;        // 12

function foo() {
   var local = 36;
   // 不过无法直接访问Activation,
   // 因此无法通过 foo.local 的方式来访问local变量
}

delete操作符删除的对象

C++中也有delete操作符,它删除的是指针所指向的对象 但Javascript的delete与C++不同,它不会删除指向的对象,而是删除属性本身

 

var o = {};
var a = { x: 10 };
o.a = a;
delete o.a;    // o.a属性被删除
o.a;           // undefined
a.x;           // 10, 因为{ x: 10 } 对象依然被 a 引用,所以不会被回收

 

 

 

 

 

 

在实际的Javascript中,delete o.x之后,Object对象会由于失去了引用而被垃圾回收,所以delete o.x也就“相当于”删除了o.x所指

 

向的对象,但这个动作并不是ECMAScript标准,也就是说,即使某个实现完全不删除Object对象,也不算是违反ECMAScript标准。

 

隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。

  • 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
  • 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。

这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

// 定义三个全局变量
var global_var = 1;
global_novar = 2; // 反面教材
(function () {
   global_fromfunc = 3; // 反面教材
}());

// 试图删除
console.log(delete global_var); // false
console.log(delete global_novar); // true
console.log(delete global_fromfunc); // true

// 测试该删除
console.log(typeof global_var); // "number"
console.log(typeof global_novar); // "undefined"
console.log(typeof global_fromfunc); // "undefined"

但是有一点例外,就是通过 eval 执行的代码中,通过var声明的变量虽然与正常的var声明变量同属于Global对象,但它们不

具有DontDelete特性,能被删除。

    eval("var x = 36;");
    console.log(x);             // 42
    console.log(delete x);         // false
    console.log(typeof x);             // undefined

eval执行代码声明的变量到底是谁哪个对象的属性,和定义他时所在的作用域有关。而且eval和浏览器也有关,FF和IE下表现也不一致。

 

delete的返回值

delete是普通运算符,会返回true或false。规则为:当被delete的对象的属性存在并且拥有DontDelete时返回false,否则返

回true。这里的一个特点就是,对象属性不存在时也返回true,所以返回值并非完全等同于删除成功与否。

    function C() { this.x = 42; }
    C.prototype.y = 12;
    var o = new C();

    console.log(delete o.x); // true
    console.log(o.x);        // undefined
    console.log("x" in o);   // false
                             // o.x存在并且没有DontDelete,返回true
    console.log(delete o.y); // true
    console.log(o.y);        // 12
    // o自身没有o.y属性,所以返回true
    // 从这里也可以看到prototype链的存在,对象自身属性和prototype属性是不同的
    
    console.log(delete o.__proto__.y);//true
    console.log(o.y);          //undefined

    console.log(delete o);   // false
    // Global.o拥有DontDelete特性所以返回false

    console.log(delete undefinedProperty);  // true
    // Global没有名为undefinedProperty的属性因此返回true

    console.log(delete 42);  // true
    // 42不是属性所以返回true。有的实现会抛出异常(违反ECMAScript标准)

    var x = 24;
    console.log(delete x++);  // true
    console.log(x);           // 25
    // 被删除的是x++的返回值(24),不是属性,所以返回true

 

 

posted @ 2013-03-04 14:33  九果子  阅读(247)  评论(0编辑  收藏  举报