天天看點

JavaScript對象的兩類屬性(資料屬性與通路器屬性)

對JavaScript來說,屬性并非隻是簡單的名稱和值,JavaScript用一組特征(attribute)來描述屬性 (property)。

第一類屬性資料屬性具有四個特征。

value:就是屬性的值。

writable:決定屬性能否被指派。

enumerable:決定for in能否枚舉該屬性。

configurable:決定該屬性能否被删除或者改變特征值。

在大多數情況下,我們隻關心資料屬性的值即可。

第二類屬性是通路器(getter/setter)屬性,它也有四個特征。

getter:函數或undefined,在取屬性值時被調用。

setter:函數或undefined,在設定屬性值時被調用。

我們通常用于定義屬性的代碼會産生資料屬性,

其中的writable、enumerable、configurable都預設為 true。

我們可以使用内置函數 Object.getOwnPropertyDescripter來檢視,

如以下代碼所示:

var o = { a: 1 }; o.b = 2; //a和b皆為資料屬性

Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}

這裡使用了兩種文法來定義屬性,定義完屬性後,我們用JavaScript的API來檢視這個屬性,

我們可以發現,這樣定義出來的屬性都是資料屬性,writeable、enumerable、configurable都是預設值為true。

如果我們要想改變屬性的特征,或者定義通路器屬性,我們可以使用 Object.defineProperty,示例如下:

var o = { a: 1 }; Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true}); //a和b都是資料屬性,但特征值變化了

Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}

o.b = 3; console.log(o.b); // 2

使用了Object.defineProperty來定義屬性,這樣定義屬性可以改變屬性的writable和enumerable。

我們同樣用Object.getOwnPropertyDescriptor來檢視,發現确實改變了writable和enumerable特征。因為writable特征為false,是以我們重新對b指派,b的值不會發生變化。

在建立對象時,也可以使用 get 和 set 關鍵字來建立通路器屬性,代碼如下所示:

var o = { get a() { return 1 } };

console.log(o.a); // 1

繼續閱讀