我在JavaScript中有一個全局變量(其實是一個window
屬性,但我認爲這並不重要),該變量已經由先前的腳本填充,可是我不但願另外一個稍後運行的腳原本查看其值或甚至定義。 瀏覽器
我已經放了some_var = undefined
,它能夠用於測試typeof some_var == "undefined"
可是我真的不認爲這是正確的方法。 安全
你怎麼看? 函數
some_var = null; //or remove it.. delete some_var;
若是您隱式聲明不帶var
的變量,則正確的方法是使用delete foo
。 測試
可是,在刪除它以後,若是嘗試在諸如加法之類的操做中使用它,則會拋出ReferenceError
由於您沒法將字符串添加到未聲明,未定義的標識符中。 例: spa
x = 5; delete x alert('foo' + x ) // ReferenceError: x is not defined
在某些狀況下,將其分配爲false,null或undefined可能更爲安全,所以將其聲明且不會引起此類錯誤。 prototype
foo = false
請注意,在ECMAScript中, null
, false
, undefined
, 0
, NaN
或''
都將取值爲false
。 只要確保您不使用!==
運算符,而是使用!=
來進行布爾類型的類型檢查而且您不但願進行身份檢查(所以null
將== false
和false == 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
,若是您足夠關心,則應閱讀:
@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
聲明的變量。
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
var
在這種狀況下,引用g_a
是在ECMAScript規範稱爲「 VariableEnvironment 」的狀況下建立的,該引用附加到當前做用域-在函數內部使用var
的狀況下,這多是函數執行上下文(儘管可能會獲得一些幫助)當您考慮let
)或在「全局」代碼的狀況下, 變量環境更加複雜, 變量環境被附加到全局對象(一般是window
)。
VariableEnvironment中的引用一般是不可刪除的-ECMAScript 10.5中詳細介紹的過程對此進行了詳細說明,但能夠這樣說,除非您的代碼在eval
上下文中執行(大多數基於瀏覽器的開發控制檯都使用該上下文),而後使用var
沒法刪除。
var
當嘗試在不使用var
關鍵字的狀況下爲名稱分配值時,Javascript嘗試在ECMAScript規範稱爲「 LexicalEnvironment 」的位置查找命名的引用,主要區別在於LexicalEvironment是嵌套的-LexicalEnvironment有一個父項(ECMAScript規範稱爲「外部環境引用」),而且當Javscript沒法在LexicalEenvironment中找到引用時,它將在父LexicalEnvironment中查找(如10.3.1和10.2.2.1中所述 )。 頂級LexicalEnvironment是「 全局環境 」,它綁定到全局對象,由於它的引用是全局對象的屬性。 所以,若是您嘗試訪問在當前範圍或任何外部範圍中未使用var
關鍵字聲明的名稱,則Javascript最終將獲取window
對象的屬性以用做該引用。 正如咱們以前所瞭解的,能夠刪除對象的屬性。
重要的是要記住var
聲明是「懸掛的」-即始終認爲它們已在它們所在範圍的開頭髮生-儘管不是在var
語句中可能完成的值初始化-留在了它是。 所以,在如下代碼中, a
是VariableEnvironment的引用,而不是window
屬性的引用,在代碼末尾,其值爲10
:
function test() { a = 5; var a = 10; }
以上討論是在未啓用「嚴格模式」的狀況下。 使用「嚴格模式」時,查找規則略有不一樣,若是沒有「嚴格模式」就能夠解析爲窗口屬性的詞法引用將在「嚴格模式」下引起「未聲明變量」錯誤。 我不太瞭解在哪裏指定它,可是它在瀏覽器中的表現如何。
除了每一個人都寫的內容外,還請注意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