Javascript的變數與delete操作符

來源:互聯網
上載者:User

轉自:http://tech.idv2.com/2008/01/09/javascript-variables-and-delete-operator/

剛剛看到一篇好文(原文連結), 對Javascript中的delete操作符分析得很透徹。在這裡簡單地介紹一下內容。

雖然是一個小小的delete操作符,其行為卻異常複雜。

Javascript的變數實際上Javascript中,變數 = 對象屬性,這是因為 Javascript 在執行指令碼之前會建立一個Global對象,所有的全域變數都是這個Global對象的屬性, 執行函數時也會建立一個Activation對象,所有的局部變數都是這個Activation對象的屬性。 如下例:
<script>var global = 42;console.log(this.global);    // 42, 可以通過this來訪問Global對象this.global2 = 12;console.log(global2);        // 12function foo() {  var local = 36;  // 不過無法直接存取Activation,  // 因此無法通過 foo.local 的方式來訪問local變數}console.log(foo.local);</script>
delete操作符刪除的對象C++中也有delete操作符,它刪除的是指標所指向的對象。例如:
// C++class Object {public:  Object *x;}Object o;o.x = new Object();delete o.x;     // 上一行new的Object對象將被釋放

但Javascript的delete與C++不同,它不會刪除o.x指向的對象,而是刪除o.x屬性本身

<script>//Javascriptvar o = {};o.x = new Object();delete o.x;     // 上一行new的Object對象依然存在console.log(o.x);            // undefined,o的名為x的屬性被刪除了</script>

在實際的Javascript中,delete o.x之後,Object對象會由於失去了引用而被記憶體回收, 所以delete o.x也就“相當於”刪除了o.x所指向的對象,但這個動作並不是ECMAScript標準, 也就是說,即使某個實現完全不刪除Object對象,也不算是違反ECMAScript標準。
“刪除屬性而不是刪除對象”這一點,可以通過以下的代碼來確認:

<script>var o = {};var a = { x: 10 };o.a = a;delete o.a;    // o.a屬性被刪除console.log(o.a);           // undefinedconsole.log(a.x);           // 10, 因為{ x: 10 } 對象依然被 a 引用,所以不會被回收</script>

另外,delete o.x 也可以寫作 delete o["x"],兩者效果相同。

能刪除的屬性和不能刪除的屬性並不是所有的屬性都能被delete。例如,prototype中聲明的屬性就無法被delete:
<script>function C() { this.x = 42; }C.prototype.x = 12;var o = new C();console.log(o.x);     // 42, 建構函式中定義的o.xdelete o.x;console.log(o.x);     // 12,  prototype中定義的o.x,即使再次執行delete o.x也不會被刪除delete C.prototype.x  //原型屬性怎麼可能通過執行個體來刪除,當然是刪除原型中的屬性console.log(o.x);</script>

對象的預定義屬性也無法刪除。 可以認為這類屬性帶有DontDelete的特性。

<script>var re = /abc/i;delete re.ignoreCase;console.log(re.ignoreCase); // true, ignoreCase無法刪除delete re.constructor.prototypeconsole.log(re.ignoreCase); // true, ignoreCase無法刪除</script>

總結:只有內建對象的屬性不能刪除,其他的任何屬性都可以刪除(不要刪除原型屬性通過執行個體)
能刪除的變數和不能刪除的變數通過var聲明的變數和通過function聲明的函數擁有DontDelete特性,無法被刪除。

<script>var x = 36;delete x;console.log(x);     // 36, x沒有被刪除y = 12;delete y;//console.log(y);     //直接報錯function foo() { return 42; }delete foo;console.log(foo());  // 42function foo2() {  var local = 36;  delete local;    // 刪除Activation.local  console.log(local);//36 函數中的局部變數是刪除不了的,原因是無法對Activation進行刪除操作}foo2();</script>

但是有一點例外,就是通過 eval 執行的代碼中,通過var聲明的變數雖然與正常的var聲明變數 同屬於Global對象,但它們不具有DontDelete特性,能被刪除。

<script>eval("var x = 36;");console.log(x);     // 36delete x;//console.log(x);     // 報錯</script>

但是這也有一點例外,eval的代碼中的函數內通過var定義的變數具有DontDelete,不能被刪除。

<script>var x = eval("(function() { var x = 42; delete x; return x; })();");console.log(x)//返回 42 </script>

delete的傳回值delete是普通運算子,會返回true或false。規則為:當被delete的對象的屬性存在並且擁有DontDelete時 返回false,否則返回true。 這裡的一個特點就是,對象屬性不存在時也返回true,所以傳回值並非完全等同於刪除成功與否。

<script>function C() { this.x = 42; }C.prototype.y = 12;var o = new C();console.log(delete o.x); // trueconsole.log(o.x);        // undefinedconsole.log("x" in o);   // false// o.x存在並且沒有DontDelete,返回trueconsole.log(delete o.y); // trueconsole.log(o.y);        // 12// o自身沒有o.y屬性,所以返回true// 從這裡也可以看到prototype鏈的存在,對象自身屬性和prototype屬性是不同的console.log(delete o);   // false// Global.o擁有DontDelete特性所以返回falseconsole.log(delete undefinedProperty);  // true// Global沒有名為undefinedProperty的屬性因此返回trueconsole.log(delete 42);  // true// 42不是屬性所以返回true。有的實現會拋出異常(違反ECMAScript標準)var x = 24;console.log(delete x++);  // trueconsole.log(x);           // 25// 被刪除的是x++的傳回值(24),不是屬性,所以返回true</script>
總結:

不可以刪除的屬性:內建對象中的屬性

不可以刪除的變數:Global對象的屬性(eval除外)  Activation對象的屬性 delete的傳回值:刪除不成功返回false,其他情況返回true

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.