如何取消設置JavaScript變量?

我在JavaScript中有一個全局變量(其實是一個window屬性,但我認爲這並不重要),該變量已經由先前的腳本填充,可是我不但願另外一個稍後運行的腳原本查看其值或甚至定義。 瀏覽器

我已經放了some_var = undefined ,它能夠用於測試typeof some_var == "undefined"可是我真的不認爲這是正確的方法。 安全

你怎麼看? 函數


#1樓

some_var = null;

//or remove it..
delete some_var;

#2樓

若是您隱式聲明不帶var的變量,則正確的方法是使用delete foo測試

可是,在刪除它以後,若是嘗試在諸如加法之類的操做中使用它,則會拋出ReferenceError由於您沒法將字符串添加到未聲明,未定義的標識符中。 例: spa

x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined

在某些狀況下,將其分配爲false,null或undefined可能更爲安全,所以將其聲明且不會引起此類錯誤。 prototype

foo = false

請注意,在ECMAScript中, nullfalseundefined0NaN''都將取值爲false 。 只要確保您不使用!==運算符,而是使用!=來進行布爾類型的類型檢查而且您不但願進行身份檢查(所以null== falsefalse == undefined )。 code

還要注意, delete並非「刪除」引用,而是直接在對象上的屬性,例如: 對象

bah = {}, foo = {}; bah.ref = foo;

delete bah.ref;
alert( [bah.ref, foo ] )
// ,[object Object] (it deleted the property but not the reference to the other object)

若是使用var聲明瞭變量,則沒法刪除它: ip

(function() {
    var x = 5;
    alert(delete x)
    // false
})();

在犀牛中: ci

js> var x
js> delete x
false

您也不能刪除一些預約義的屬性,例如Math.PI

js> delete Math.PI
false

與任何語言同樣,有一些奇怪的例外要delete ,若是您足夠關心,則應閱讀:


#3樓

@scunlife的答案會起做用,但從技術上講應該是

delete window.some_var;

當目標不是對象屬性時,delete應該被禁止使用。 例如,

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

可是因爲全局變量其實是window對象的成員,所以它能夠工做。

當涉及到原型鏈時,使用delete會變得更加複雜,由於它只會從目標對象而不是原型中移除屬性。 例如,

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

因此要當心

編輯:個人回答有點不許確 (請參閱末尾的「誤解」)。 該連接說明了全部詳細信息,但摘要是,瀏覽器之間以及要刪除的對象之間可能會有很大差別。 只要object !== window delete object.someProp一般應該是安全的。 儘管您能夠在適當的狀況下使用,但我仍然不會使用它來刪除用var聲明的變量。


#4樓

delete運算符從對象中刪除屬性。 它不能刪除變量。 所以,問題的答案取決於如何定義全局變量或屬性。

(1)若是使用var建立,則沒法刪除。

例如:

var g_a = 1; //create with var, g_a is a variable 
delete g_a; //return false
console.log(g_a); //g_a is still 1

(2)若是不使用var建立它,則能夠將其刪除。

g_b = 1; //create without var, g_b is a property 
delete g_b; //return true
console.log(g_b); //error, g_b is not defined

技術說明

1.使用var

在這種狀況下,引用g_a是在ECMAScript規範稱爲「 VariableEnvironment 」的狀況下建立的,該引用附加到當前做用域-在函數內部使用var的狀況下,這多是函數執行上下文(儘管可能會獲得一些幫助)當您考慮let )或在「全局」代碼的狀況下, 變量環境更加複雜, 變量環境被附加到全局對象(一般是window )。

VariableEnvironment中的引用一般是不可刪除的-ECMAScript 10.5中詳細介紹的過程對此進行了詳細說明,但能夠這樣說,除非您的代碼在eval上下文中執行(大多數基於瀏覽器的開發控制檯都使用該上下文),而後使用var沒法刪除。

2.不使用var

當嘗試在不使用var關鍵字的狀況下爲名稱分配值時,Javascript嘗試在ECMAScript規範稱爲「 LexicalEnvironment 」的位置查找命名的引用,主要區別在於LexicalEvironment是嵌套的-LexicalEnvironment有一個父項(ECMAScript規範稱爲「外部環境引用」),而且當Javscript沒法在LexicalEenvironment中找到引用時,它將在父LexicalEnvironment中查找(如10.3.110.2.2.1中所述 )。 頂級LexicalEnvironment是「 全局環境 」,它綁定到全局對象,由於它的引用是全局對象的屬性。 所以,若是您嘗試訪問在當前範圍或任何外部範圍中未使用var關鍵字聲明的名稱,則Javascript最終將獲取window對象的屬性以用做該引用。 正如咱們以前所瞭解的,能夠刪除對象的屬性。

筆記

  1. 重要的是要記住var聲明是「懸掛的」-即始終認爲它們已在它們所在範圍的開頭髮生-儘管不是在var語句中可能完成的值初始化-留在了它是。 所以,在如下代碼中, aVariableEnvironment的引用,而不是window屬性的引用,在代碼末尾,其值爲10

    function test() { a = 5; var a = 10; }

  2. 以上討論是在未啓用「嚴格模式」的狀況下。 使用「嚴格模式」時,查找規則略有不一樣,若是沒有「嚴格模式」就能夠解析爲窗口屬性的詞法引用將在「嚴格模式」下引起「未聲明變量」錯誤。 我不太瞭解在哪裏指定它,可是它在瀏覽器中的表現如何。


#5樓

除了每一個人都寫的內容外,還請注意delete返回布爾值。 它能夠告訴您刪除是否成功。

在Chrome上進行測試,除let以外的全部內容均可以刪除。 當delete返回true ,實際上刪除了它們:

implicit_global = 1;
window.explicit_global = 1;
function_set = function() {};
function function_dec() { };
var declared_variable = 1;
let let_variable = 1;

delete delete implicit_global; // true, tested on Chrome 52
delete window.explicit_global; // true, tested on Chrome 52
delete function_set; // true, tested on Chrome 52
delete function_dec; // true, tested on Chrome 52
delete declared_variable; // true, tested on Chrome 52
delete let_variable; // false, tested on Chrome 78
相關文章
相關標籤/搜索