對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