JavaScript對象屬性的特性

除了包含名字和值以外,屬性還包含的一些標識它們可寫、可枚舉和可配置的特性。數據屬性的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()

經過調用Object.getOwnPropertyDescriptor()能夠得到某個對象特定屬性的描述符:code

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

Object.getOwnPropertyDescriptor()只能獲得自有屬性的描述符。對象

Object.defineProperty()與Object.defineProperties()

要想設置屬性的特性,或者想讓新建屬性具備某種特性,則須要調用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

  • 若是對象是不可擴展的,則能夠編輯已有的自有屬性,但不能給它添加新屬性。
  • 若是屬性是不可配置的,則不能修改它的可配置性和可枚舉性。
  • 若是存取器屬性是不可配置的,則不能修改其getter和setter方法,也不能將它轉換爲數據屬性。
  • 若是數據屬性是不可配置的,則不能將它轉換成存取器屬性。
  • 若是數據屬性是不可配置且不可寫的,則不能修改它的值。然而可配置但不可寫屬性的值是能夠修改的(其實是先將它標記爲可寫的,而後修改它的值,最後轉換爲不可寫的)。
相關文章
相關標籤/搜索