除了包含名字和值以外,屬性還包含的一些標識它們可寫、可枚舉和可配置的特性。數據屬性的4個特性分別是它的值(value)、可寫性(writable)、可枚舉性(enumerable)和可配置性(configurable)。存取器屬性的4個特性是讀取(get)、寫入(set)、可枚舉性和可配置性。函數
ECMAScript中有一個名爲「屬性描述符」(property descriptor)的對象,這個對象表明那4個特性。描述符對象的屬性和他們所描述符的屬性特性是同名的。所以數據屬性的描述符對象有value、writable、enumerable和configurable。存取器屬性的描述符對象則用get屬性和set屬性代替value和writable。其中writable、enumerable和configurable是布爾值,get屬性和set屬性是函數值。this
經過調用Object.getOwnPropertyDescriptor()能夠得到某個對象特定屬性的描述符:code
Object.getOwnPropertyDescriptor({x:1},"x"); //{value:1,writable:true,enumerable:true,configurable:true}
Object.getOwnPropertyDescriptor()只能獲得自有屬性的描述符。對象
要想設置屬性的特性,或者想讓新建屬性具備某種特性,則須要調用Object.defineProperty(),傳入要修改的對象,要建立或要修改的屬性,以及屬性描述符對象。繼承
var o = {}; // 添加一個不可枚舉的數據屬性x,並賦值爲1 Object.defineProperty(o, "x", { value:1, writable: true, enumerable:false, configurable: true});
傳入Object.defineProperty()的屬性描述符對象沒必要包含4個特性。對於新建立的屬性來講,默認的特性值是false或undefined。對於修改的已有屬性來講,默認的特性值沒有作任何修改。這個方法要麼修改已有屬性要麼新建自有屬性,但不能修改繼承屬性。
若是要同時修改或建立多個屬性,則須要使用Object.defineProperties()。第一個參數是要修改的對象,第二個參數是一個映射表,它包含要新建或修改的屬性的名稱,以及它們的屬性描述符,例如:ip
var p = Object.defineProperties( x: { value:1, writable: true, enumerable:false, configurable: true}, y:{ value:1, writable: true, enumerable:false, configurable: true}, r: { get: function() { return Math.sqrtthis.x*this.x + this.y*this.y) }, enumerable:false, configurable: true } });
用Object.defineProperty()與Object.defineProperties()操做對象屬性的特性也是要遵循必定的規則的。任何違反規則的使用會拋出類型錯誤異常。下面是完整的規則:get