想了解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
|
就是屬性值,對象在讀取屬性值時就是從這個位置讀取的.
|
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/