javascript delete機制學習


想了解delete的機制緣起一個現象,我無法解釋,也無法理解。

首先看一下下面這個例子:
var x = 1;
delete x; //false
然后我又執行了一次:
y = 2;
delete y; //true
看到上面的結果,我比較吃驚,為什么同樣是刪除,區別怎么這么大呢?進而我想學習和了解一下JS delete的機制。
 在MDN(Mozilla Developer Network)上看到下面一個例子
x = 42;         // creates the property x on the global object
var y = 43;     // declares a new variable, y
myobj = {
  h: 4,
  k: 5
};

delete x;       // returns true  (x is a property of the global object and can be deleted)
delete y;       // returns false (delete doesn't affect variable names)
delete Math.PI; // returns false (delete doesn't affect certain predefined properties)
delete myobj.h; // returns true  (user-defined properties can be deleted)

delete myobj;   // returns true  (myobj is a property of the global object, not a variable, so it can be deleted)
我們可以看出,delete元算符執行的結果要么是true,要么是false。那么什么時候返回true,什么時間返回false呢?
簡單的總結了一句話: 只要可以被刪除,就會返回true(看起來像是一句廢話,可能實際上也是一句廢話)
 
此時我們要討論的就是什么時候才能被刪除?
 
總結上面的例子我們發現:
1.在global object上的屬性可以被刪除;
2.聲明的變量不能被刪除
3.未聲明的全局變量可以被刪除
4.內置對象的屬性不能被刪除
 
為什么會有這個結果?
要想知道原理,首先了解兩個概念:上下文和屬性特性。
 
1.上下文
我們知道每條語句在執行的時候,他都會處在一個環境中,這個環境就是這條語句的上下文環境。當一個函數執行時,會進入函數代碼執行的上下文;全局代碼執行時,會進入全局代碼執行的上下文。每個執行上下文中都會存在一個內部的可變對象(variable object),當進入這個環境的時候,會實例化這個可變對象,然后聲明的變量和方法,都會作為這個可變對象的屬性。那么在上述所說到的兩個執行環境就會實例化兩種對象,全局對象(global object)和激活對象(activation object)。
2.屬性特性
ECMAScript5中可以查詢,設置這些 特性 。我們將存取器 屬性 的getter,setter方法看成是 屬性 特性 ,同理,可以把數據 屬性 的值看做 屬性 特性 所以可認為一個 屬性 包含一個名字和4個 特性(見下表)  ECMACScript5定義了一個名為“ 屬性 描述符”的 對象 。這個 對象 代表那4個 特性 通過 Object.getOwnPropertyDescriptor(object, propertyname) 可以獲得某個 對象 特定 屬性 屬性 描述符。
特性名
說明
Configurable
設置屬性是否可配置,即能否更改(包括名值)或者刪除(delect)它,能否修改屬性特性等等
Enumerable
設置屬性是否可以枚舉,即能否通過for-in循環返回
Writable
是否可寫
Value
就是屬性值,對象在讀取屬性值時就是從這個位置讀取的.
這里delete會涉及到 Configurable特性。可通過上述方法 getOwnPropertyDescriptor 簡單判斷是否可以delete。開始說的兩個例子的結果如下:
var x = 1;
Object.getOwnPropertyDescriptor(window, 'x'); //configurable= false
delete x; //false
y = 2;
Object.getOwnPropertyDescriptor(window, 'y'); //configurable= true
delete y; //true
這里還需要交代的是,屬性的特性是在創建的時候就確定的,賦值並不能改變它的特性,
function sum() {}
sum = 1;
Object.getOwnPropertyDescriptor(window, 'sum'); //configurable= false
delete sum; //false
但是可以通過這個方法定義的特性值 Object.defineProperties(object, descriptors),
Object.defineProperties(window, {sum1:{value:1,configurable:true}});
Object.getOwnPropertyDescriptor(window, 'sum'); //configurable= true
delete sum1; //true
Object.defineProperties(window, {sum2:{value:1,configurable:false}});
Object.getOwnPropertyDescriptor(window, 'sum'); //configurable= false
delete sum2; //false
 
總結一下delete不能刪除屬性:
 
1.聲明的變量(變量、函數、函數參數)不能刪除;如:var x=1;
2.內置對象的屬性不能刪除;如:Math.PI
3.定義的變量屬性的configurable值為false的,不能刪除。
注意:IE6-8下delete window屬性會報類型錯誤
 
 
參考文獻:
http://blog.csdn.net/jiushuai/article/details/6020739
http://perfectionkills.com/understanding-delete/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM