Object.defineProperty 與 屬性描述符

爲JavaScript對象新增或者修改屬性,有兩種不一樣方式:直接使用=賦值或者使用Object.defineProperty 定義,使用後者的話還能夠設置屬性的描述符。函數

Object.defineProperty

Object.defineProperty(obj, prop, descriptor) 接受三個參數:this

  1. obj:要在其上定義屬性的對象。
  2. prop:要定義或修改的屬性的名稱。
  3. descriptor:將被定義或修改的屬性描述符。

屬性描述符

屬性描述符是一個對象,做用就是定義一個屬性的屬性 (-,-)。他有兩種主要形式:數據描述符和存取描述符。code

數據描述符是一個具備值的屬性,該值多是可寫的,也可能不是可寫的,特有屬性:value、writable。存取描述符是由getter-setter函數對描述的屬性,特有屬性:get、set。描述符必須是這兩種形式之一;不能同時是二者。對象

Object.getOwnPropertyDescriptor() 能夠獲取指定對象上一個自有屬性對應的屬性描述符。



繼承

數據描述符和存取描述符均具備如下可選鍵值:ip

1. configurable

表示對象的該屬性是否能夠被刪除,以及其餘特性是否能夠被修改(除了能夠單向改變 writable 爲 false)。默認爲 false。get

let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174
})
delete Tom.height
console.log(Tom)   //  {height: 174}
let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174,
  configurable: true
})
delete Tom.height
console.log(Tom)   // {}

2. enumerable

當定義了對象的屬性是否能夠在 for...in 循環和 Object.keys() 中被枚舉。默認爲 false。it

let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174
})
Object.keys(Tom)   // []
let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174,
  enumerable: true
})
Object.keys(Tom)   // ["height"]





數據描述符具備如下可選鍵值:io

1. value

該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲 undefined。console

2. writable

當且僅當該屬性的writable爲true時,value才能被賦值運算符 「=」 改變。默認爲 false。

let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174
})
Tom.height = 180 
console.log(Tom)   // {height: 174}

Object.getOwnPropertyDescriptor(Tom,'height')
//  {value: 174, writable: false, enumerable: false, configurable: false}
let Tom = {}
Object.defineProperty(Tom, 'height', {
  value: 174,
  writable: true
})
Tom.height = 180 
console.log(Tom)   // {height: 180}

使用「=」定義屬性時,writable/enumerable/configurable 都爲true:

let Tom = {}
Tom.height = 174

Object.getOwnPropertyDescriptor(Tom,'height')
// {value: 180, writable: true, enumerable: true, configurable: true}


存取描述符同時具備如下可選鍵值:

1. get

一個給屬性提供 getter 的方法,若是沒有 getter 則爲 undefined。當訪問該屬性時,該方法會被執行,方法執行時沒有參數傳入,可是會傳入this對象(因爲繼承關係,這裏的this並不必定是定義該屬性的對象)。

2. set

一個給屬性提供 setter 的方法,若是沒有 setter 則爲 undefined。當屬性值修改時,觸發執行該方法。該方法將接受惟一參數,即該屬性新的參數值。

let Tom = {
  realHeight: 173
}

Object.defineProperty(Tom, 'height', {
  get: function() {
    console.log('報高一點')
    return this.realHeight + 5;
  },
  set: function(value) {
    console.log('如今高' + value + 'cm')
    this.realHeight = value
  }
})

Object.getOwnPropertyDescriptor(Tom,'height')
//  {get: ƒ, set: ƒ, enumerable: false, configurable: false}

Tom.height        // 178
Tom.height = 169
Tom.height        //  174
相關文章
相關標籤/搜索