一、變數
說到javascript中的delete操作符,還是先搞清楚javascript中的變數和屬性之間的關係。
javascript中,變數和對象屬性關係非常微妙,甚至可以很多時候會被等同起來,因為javascript 在執行腳本之前會創建一個global對象,在瀏覽器中就是window對象,所有的全域變數都是這個global物件的屬性,執行函數時也會建立一個activation對象,所有的局部變數都是這個activation物件的屬性。這些可以大家可以去了解javascript作用域和閉包。
//原型中宣告的屬性無法刪除>
var global = 1;
this.global; // 1, 可以透過this來存取global物件
this.global2 = 2;
global2; // 12
function foo( ) {
var local = 36;
// 不過無法直接存取activation,
// 因此無法透過foo.local 的方式來存取local變數
}
似乎變數就等同於物件屬性,其實不然,至少對於delete運算子來說還是不一樣的。我的理解是變數宣告是必須透過 var 語句來完成的,未透過var 語句宣告的全域變數都是window物件的屬性。這樣就很容易的理解變數和物件屬性的關係了。
二、delete運算符
delete操作符是用來刪除物件屬性的。對於引用類型的值,它也是刪除物件屬性的本身,不會刪除屬性指向的物件。如果有疑問可以看看基本類型和引用類型的值,或測試下面的程式碼:
var o = {};
var a = { x: 10 };
o.a = a;
delete o.a; // o.a屬性刪除
cons. log(o.a); // undefined
console.log(a.x); // 10, 因為{ x: 10 } 物件仍被a 引用,所以不會被回收
另外,delete o.x 也可以寫作 delete o["x"],兩者效果相同。
三、變數是不能刪除的
透過var宣告的變數和透過function宣告的函數擁有dontdelete特性,是不能被刪除。未透過var宣告的全域變數(全域物件的屬性)
>var global = {
a: 123,
b: {
c: 1345
}
obj = {
a: 123
};
delete obj; // 刪除obj全域變量,window物件的obj屬性
console.log(obj); /obj is not defined
四、原型中宣告的屬性和物件自帶的屬性無法被刪除
原型prototype中宣告的屬性和物件自帶的屬性(其實這些屬性也是在原型prototype中的)可以認為是帶有dontdelete的特性的,無法被刪除。例如
複製程式碼
function obj() {
this.x = 1;
}
obj.prototype.x = 2;
var o = new obj();
console.log(o.x); // 1, 建構子中定義的o.x
delete o.x;
console.log(o.x); // 2, prototype中定義的o.x,即使再次執行delete o.x也不會被刪除
//物件自帶的屬性無法被刪除
var strings = "123456";
console.log(strings.length);// 6
delete strings.length;
console.log(strings.length);//依然6
五、eval語句下的幾個例外
eval執行的程式碼中,透過var宣告的變數雖然與正常的var宣告變數同屬於global對象,但它們不具有dontdelete特性,且能被刪除。但是eval的程式碼中的函數內透過var定義的變數具有dontdelete,不能被刪除。
複製程式碼