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