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