2012-01-30 75 views
7

出的只是知識的好奇心,爲什麼JavaScript的接受Javascript:z = z ||不使用VAR時,[]會拋出錯誤 - 爲什麼?

var z = z || []; 

初始化Z(如z可最初定義)

但沒有變種,它拋出一個錯誤(在全球空間)

z = z || []; 

(如果Z先前未定義)

在全球空間,您不需要使用VAR雖然我得到它可能b不好的做法。

之前你說這是一個問題,如

What is the purpose of the var keyword and when to use it (or omit it)?

注意的聲明重複「如果在全球範圍內是那麼有沒有什麼區別。」

顯然這不是100%真實的,因爲我的工作示例。

這是一個怪癖還是有合法的邏輯?


添加答案的總結,因爲我已經學會了:

感謝Tim(見下文)的關鍵,我的誤解並沒有意識到這一點(基本的javascript)

var z;如果z已經存在,則絕對不會執行任何操作。

如果您不正確地假定「var z」總是初始化,那麼這就是這種表達式似乎具有的方式。

從左側開始,「var z」只是確保z已定義,但實際上並不影響現有值(如果已存在)。然後在右邊,如果z已經存在,則使用它,如果不存在,則該變量剛剛聲明(但爲空),因此它不會被使用,但不會引發錯誤。

這是對這種確定範圍和在Javascript吊裝問題的一個很好的文章: http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

非常感謝MiniTech移動和其他人誰貢獻呢!

+2

作爲一般規則:複製實際的錯誤信息通常比寫入「拋出錯誤」更有幫助。 – 2012-01-30 16:04:54

回答

6

z = z || []將在範圍鏈中沒有z的地方投擲任何範圍(全局或不是)。原因是表達式首先嚐試檢索右側存在的名爲z的變量的值,如果不存在,則該值爲錯誤。

爲什麼var z = z || []不會引發錯誤的原因是變量z被創建(如果它不存在的話)執行表達式之前,一個效果俗稱吊裝

另一方面,將值分配給未解析的標識符(例如z = 2)將在任何作用域(除ECMAScript 5嚴格模式,禁止它和拋出)外無錯誤地工作。如果標識符無法解析,它將作爲作用域鏈中最終對象的屬性添加,作爲全局對象,因此給出了創建全局變量的外觀。

+0

啊我想我明白了。因此,「var z」首先在左側完成,就像指示「創建一個新的z」一樣,然後在右側尋找一個「老z」。按照該順序,「z」剛剛在左側初始化,因此右側的「z」不是未定義的,儘管它是空的。如果沒有var,右邊的「z」不只是空的,它是未定義的。嗯好吧 - 如果「var z」將它定義爲新的左邊,那麼這段代碼如何保留現有的值呢?看起來它有兩種方式,左邊爲右邊初始化,但也可以保持右邊的值。 – 2012-01-30 16:52:38

+0

@ck_:是的,我認爲你已經知道了,儘管術語需要注意,因爲undefined是JavaScript中的一個實際值,實際上它是分配給變量的默認值(例如'var x;'創建一個名爲'x'的變量,其初始值爲undefined,與從未聲明的不存在的'x'不同。我會去「未申報」或「不存在」。 – 2012-01-30 16:56:31

+0

@ck_:關於保留現有值,如果'z'已經存在,'var z;'什麼都不做,不管它的值如何。 – 2012-01-30 17:01:00

10

效果是正確的。 var將總是立即聲明它的「操作數」,而當你不聲明它時,你的腳本嘗試使用未定義的變量並引發錯誤。

如果您處於全局範圍內,您可以分配給一個不存在的變量,它將具有與聲明它相同的效果,這可能是錯誤的做法。當然,在你的情況下,它是不確定的。這是說,雖然這可能是出於好奇心,你就永遠不會

var z = z || []; 

,因爲它是沒有意義的這樣做。相反,你可能會這樣做:

if(!window.z) { 
    window.z = []; 
} 

。事實上,當我在全球範圍內聲明事物(從來沒有;))時,我使用window.something來代替它,因爲它使我的意圖更加清晰。

+0

**當你沒有聲明它時,你的腳本嘗試使用未定義的變量** - 等待你說z = z訪問z但var z = z不是?第二個z仍然在全局範圍內,如果它在函數之外,它仍然是第一個。 (困惑) – 2012-01-30 16:43:44

+1

@ck_:不同之處在於使用'var'會導致在任何語句執行之前創建'z'變量。 – 2012-01-30 16:51:29

4

您可以指定一個未聲明的變量z = 123;但是你可能不會嘗試閱讀z = z || []所做的一個。

相關問題