JavaScript 核心觀念(25)-物件-未定義的物件屬性預設值
前言
接下來講講未定義的物件屬性與 undefined
的關連性吧。
未定義的物件屬性預設值
首先 undefined
與未定義的物件屬性是有非常大的關係,首先先來看以下範例是一個常見的物件實字
1 | var obj = { |
當若我們要取得 obj
的 name
的話,我們可以使用點運算子或是中括號的方式取得 name
1 | obj.name; // Ray |
但是如果我們點運算子後方帶上的是一個不存在的屬性的話,那麼會發生什麼事情
1 | obj.status; // undefined |
因此我們這邊可以知道一件事情,若輸入的不存在的屬性就會出現 undefined
,但是如果輸入到第三層會發生什麼事情呢?也會是 undefined
嗎?
1 | obj.status.name; // VM66:1 Uncaught TypeError: Cannot read property 'name' of undefined |
這時候或許你會感到疑惑為什麼不是 undefined
呢?以錯誤訊息來講他是在說「你無法讀取 undefined
的 name
屬性」,試著回頭思考一下一開始我們知道 obj.status
會出現 undefined
,因此問題就是出在第二層未定義的物件屬性上。
那麼問題是出在哪呢?首先這問題最主要與運算子的優先性及相依性有一定關係,我們在前面章節知道,若運算子在同一行有相同優先性的運算子,那麼就會改判斷相依性,在這邊點運算子的相依性是由左至右,因此左邊會優先取得物件屬性
1 | obj.status; // undefined |
接下來才會執行後面的 status.name
,但是在前面我們已經知道 obj.status
執行後的結果是 undefined
,因此實際的運作結果就會像這樣
1 | undefined.name; |
這也就是為什麼會出現 VM66:1 Uncaught TypeError: Cannot read property 'name' of undefined
的錯誤原因,其中還有一個重點是原始型別是不允許有自己的屬性,因此就算你針對 undefined
是無法新增成功的,所以上面的錯誤訊息意思是「你無法針對 undefined
增加一個 name
屬性。」
1 | undefined.name = 'qq123' // Uncaught TypeError: Cannot set property 'name' of undefined |
但是其他原始型別在錯誤上可能會有一點不同。
1 | null.name = 'qq123'; // VM309:1 Uncaught TypeError: Cannot set property 'name' of null |
而要解決這個問題的方法有兩種,一種是預先定義物件屬性
1 | var obj = { |
那麼另一種方式則是有可能我們在寫程式時,無法確定程式碼結構,但我們可以透過賦予方式解決
1 | var obj = { |
另外這邊還有一件很特別的事情,如果你直接在瀏覽器上輸入 console.log(a);
是會出現 ReferenceError: a is not defined
,這是因為這個 a
並不存在所導致,但是如果你輸入的是 console.log(window.a);
,那麼你會發現竟然出現 undefined
。
1 | console.log(a); // ReferenceError: a is not defined |
除此之外你還可以發現一件事情就是,當發生錯誤之後,程式碼就會立刻中斷不會往後執行。
而這兩者的差異在於物件取值時,有一個保護機制,而這個保護機制最主要是避免存取到一個不存在的屬性而導致 JavaScript 發生錯誤而中斷程式碼的運作唷。