輕鬆學習 JavaScript(7):物件屬性描述符

發表於2018-01-11

在JavaScript中,你可以如下所示建立一個物件字面量:

乍一看,好像物件cat有字串和數字值這兩個屬性。然而,這不僅僅是JavaScript直譯器。在ES5中,介紹了屬性描述符的概念。在我們繼續討論屬性描述符之前,讓我們試著回答幾個問題:

  • 如何建立只讀屬性?
  • 如何制定不可列舉的屬性?
  • 如何使屬性不可配置?
  • 如何確定一個屬性是否是隻讀的?

如果你理解屬性描述符,那麼你就可以回答所有這些問題。

請看下面的程式碼:

輸出將如下所示:

p12500

正如你在這裡看到的,這個屬性有四個特徵:

value儲存屬性的資料,而writable,enumerable和configurable則描述屬性的其他特徵。接下來我們將對這些特徵一一闡述。

writable

屬性的值是否可以更改是由writable特徵決定的。如果writable設定為false,那麼屬性的值不能更改,JavaScript將忽略屬性值中的任何更改。請看下面的程式碼:

你可以使用Object.defineProperty更改writable、enumerable和configurable特徵的值。我們稍後會在這篇文章中詳細討論Object.defineProperty,但正如你在上面的程式碼片段中看到的那樣,我們已經將writable屬性設定為false,從而改變了name屬性的值。JavaScript將忽略重新分配,並且name屬性的值將保持為foo。

如果以嚴格模式執行程式碼,那麼為了重新分配writable設定為false的屬性值,JavaScript將丟擲異常。請看下面的程式碼:

在這裡,JavaScript以嚴格模式執行,因此,當你重新分配name屬性的值時,JavaScript將丟擲異常,如下所示:

p20652

這裡的錯誤訊息說,你不能賦值到只讀屬性。也就是說,如果屬性的writable特徵設定為false,那麼屬性將充當只讀屬性。

configurable

屬性的其他特徵是否可以配置取決於configurable的值。如果屬性configurable設定為false,則不能更改writable和enumerable的值。請看下面的程式碼:

在這裡,我們將name屬性的configurable設定為false。之後,我們將enumerable設定為false。如前所述,一旦一個屬性的configurable設定為false,那麼你就不能改變另一個特徵。

對於上面的程式碼,JavaScript會丟擲一個TypeError異常,如下圖所示。你會得到無法重新定義屬性名稱的錯誤:

p34237

在使用configurable的時候,你需要記住,改變configurable的值只能做一次。如果將屬性的configurable設定為false,那麼你就不能重新分配它;你無法撤消對configurable的更改。請看下面的程式碼:

我們在重新分配name屬性的configurable,但是,JavaScript會對上述操作丟擲一個TypeError,如下圖所示。正如你所看到的,一旦configurable被設定為false,就不能撤銷那個更改。

p44863

另一個重要的事情是,即使configurable設定為false,writable也可以從true更改為false——但反之則不然。請看下面的程式碼:

如果不是在嚴格模式下,上面的程式碼不會丟擲任何異常。正如我們前面所討論的,即使configurable為false,writable也可以從true變為false,反之則不然。另一個需要牢記的重要事項是,你無法刪除configurable設定為false的屬性。

在上面的程式碼中,你會發現JavaScript不會刪除name屬性,因為name屬性的configurable設定為false。

enumerable

對於一個屬性,如果你設定了enumerable:false,那麼這個屬性將不會出現在列舉中,因此它不能用在諸如for … in迴圈這樣的語句中。

請看下面的程式碼:

在這裡,你只能得到age,因為name的enumerable被設定為了false。這是另一個需要記住的重要事項:通過設定enumerable:false,唯一的屬性將不可用於列舉。我們來看下面的程式碼:

在這裡,name屬性enumerable設定為false,但你可以訪問它。在檢查name是否屬於cat的屬性時,你也會發現是true。

有時,你可能需要檢查某個特定屬性enumerable是否設定為false或true。你可以通過使用propertyIsEnumerable方法來做到這一點:

結論

作為一名專業的JavaScript開發人員,你必須對JavaScript物件屬性描述符有一個很好的理解,我希望你能從這篇文章中學到一些知識!請繼續關注我們的下一篇文章,繼續學習JavaScript中更重要的概念。

相關文章