整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
JavaScript 核心觀念(54)- 物件屬性延伸章節:屬性的特徵 - 屬性特徵是什麼?
前言
接下來將會額外補充關於物件的屬性特徵,而這邊的觀念理解後,是可以大大增加自己對於框架的理解有幫助。
屬性特徵
其實一般來說,你在 Chrome 輸入以下程式碼,就只會看到單純的物件:
1 | |
在此其實你並沒有辦法透過 Chrome 直接看到物件的屬性特徵,所謂的屬性特徵是什麼意思呢?舉凡這個屬性能不能被新增、重新寫入或者是透過迴圈讀取等,而這個屬性特徵若要觀看的話,則必須使用一個語法才可以,也就是 Object.getOwnPropertyDescriptor。
Object.getOwnPropertyDescriptor 的用法並不困難,第一個參數通常是物件本身,第二個則是要查看的屬性:
1 | |
基本上當你貼入到 Chrome 後應該會看到以下資訊
1 | |
這四個參數就是物件屬性特徵,分別為:
configurable- 屬性可否被設定- 簡單來講就是這是屬性能不能被修改 or 刪除屬性。
enumerable- 屬性可否被列舉- 最簡單來講就是,可不可以被迴圈讀取出來。
value- 值writable- 屬性的值可否被寫入- 簡單來講就是能不能被修改屬性本身的值,例如 Ray 改成 Hello。
那麼前面講那麼多,我們實際上如果想針對物件的屬性調整特徵的話該怎麼做?這邊就會使用 Object.defineProperty 來調整屬性特徵,Object.defineProperty 需要帶入的參數就有三個,第一個是要調整的物件,第二個則是要調整的屬性,第三個則是屬性特徵的調整,假使來講,我希望 myName 這個屬性不可以再次被調整的話,則是這樣子使用:
1 | |
雖然當你複製貼上上述程式碼到 Chrome 之後會看到回傳一個 Hello 的字眼,但實際上若你查看 console.log(obj.myName); 則會發現屬性依然是 Ray,請注意這邊是靜默錯誤,因此不會出現錯誤提示,你也可以試著將程式碼修改成以下:
1 | |
基本上調整完之後,你就會看到錯誤訊息「Uncaught TypeError: Cannot assign to read only property 'myName' of object '#<Object>'」,白話文就是,你不能針對不可寫入的屬性做調整,目前它只可以被讀取。
反之如果你希望屬性不被刪除的話,則是這樣調整:
1 | |
當你將屬性的 configurable 設置為 false 之後,就會發現 delete 物件時是回傳一個 false。
最後一個則是 enumerable,enumerable 比較特別一點,這邊直接看一個範例,通常我們要讀取出物件中的屬性會使用 for 讀取出來:
1 | |
但是如果你將 enumerable 改成 false 之後,則會直接消失變成 undefined:
1 | |
就算你使用較新的語法也是一樣的
1 | |
value 我就不再多介紹,簡單來講就是重新設置值的概念而已,當然你也可以用 defineProperty 來更新值,可是通常來講你會乾脆寫 obj.myName = 'Hello Ray' 而不太會寫 Object.defineProperty(obj, 'myName', { value: 'Hello Ray' }); (笑)。
defineProperty 額外有一個小雷點,它只能做到淺層的設置與保護,若是深層物件則沒有辦法
1 | |
當然 defineProperty 還有另一種大量調整的語法,假使有兩個以上的屬性特徵要調整,一個一個使用 Object.defineProperty 就會顯得很麻煩,因此就可以使用 Object.defineProperties,而寫法也非常雷同:
1 | |
參考文獻
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ