2015-08-09 47 views
1

當我嘗試使用未聲明的變量時,我得到ReferenceErrorjavascript對象的怪異行爲

console.log(a); 
Uncaught ReferenceError: a is not defined 

我可以先使用一個變量,然後再定義它,它不會因爲提升而出現問題。

console.log(a); 
var a; 
undefined 

但是當我聲明一個對象時,爲什麼執行上下文讓我使用它的任何屬性。

var obj = {}; 

console.log(obj.a); 
console.log(obj.why); 
undefined 
undefined 

爲什麼這些允許即使awhy從來沒有在任何地方申報?

+0

不完全是一個*重複*,但很好的解釋差異:http://stackoverflow.com/questions/10102862/referenceerror-and-the-global-object – CodingIntrigue

回答

2

語言設計已指定嘗試訪問對象上不存在的屬性將簡單地返回undefined

var obj = {}; 
console.log(obj.a); // undefined 

但是,試圖訪問當前或父範圍內任何地方未定義的變量是一個ReferenceError。

console.log(b);  // ReferenceError 

爲什麼這些允許即使爲什麼從來沒有宣佈 地方?

這只是語言設計的方式。我可以看到一些這樣的理由,但是決定這樣做的真正原因只在於一些原始設計師的頭腦中。我們現在的工作就是了解它是如何工作的,並編寫與當前設計兼容的代碼(因爲我們無法更改當前的語言設計)。


有辦法通過測試這些不確定的變量,如工作,解決此問題:

if (typeof b === "undefined") 

或者,如果你在瀏覽器中是和你希望b是一個全球性的,你可以使用全局連接到window對象和丟失對象的屬性不喜歡這個創建ReferenceErrors事實:

console.log(window.b); // undefined 
+0

「我可以看到一些原因是這樣的」你認爲他們是什麼?我希望知道更好地理解內部錯誤 – dogant

+0

@wheee - 當您不希望在下游代碼中可能非常混亂或混亂時,意外引用未定義的變量的後果。這似乎是一個合理的線條,並且說這可能是一個無意識的東西,應該拋出一個錯誤,特別是因爲如果你實際上是在故意處理一個可能未定義的變量,那麼有辦法解決它。是的,JS確實讓你以其他方式在腳下自己射擊,但是必須在某處畫出一條線,並且他們決定在這裏劃一條線。 – jfriend00

3

因爲對象屬性不是變量。規則是不同的。訪問一個不存在的對象屬性會給你undefined,而不是一個錯誤。這只是語言設計的方式。

一個可能的解釋的區別,不僅僅是其他說:「這是艾希怎麼設計的,」是你不聲明對象屬性。你只是用它們。但是必須聲明變量(除了The Horror of Implicit Globals之外,現在我們沒有那種嚴格模式)。