關於 Object.defineProperty()

一般,定義或者修改一個JS對象,有如下方式:函數

// 1. 字面量

let obj = {
    name: 'cedric',
    age: 18
}


// 2. new Object()
let obj = new Object()
obj.name = 'cedric'
obj.age = 18


// 3. Object.create()

// 4. 工廠模式

// 5. 構造函數

// 6. ...

上面當對象建立一個屬性後,如:obj.name = 'cedric', 其中 name 就是一個 【普通屬性】,ta的值容許修改或刪除,也能夠經過for..inObject,keys 枚舉遍歷。this

若是要更精準的控制對象屬性,能夠使用 Object.defineProperty()方法。code

語法

Object.defineProperty(obj, prop, descriptor)

// obj: 須要定義屬性的當前對象
// prop: 當前須要定義或修改的屬性名
// descriptor: 屬性描述符

例如:對象

let obj = {}; // 建立一個新對象

// 在對象中添加一個屬性與數據描述符的示例
Object.defineProperty(obj, "name", {
  value : 'cedric',   // 屬性 value 的初始化值 cedric
  writable : true,    // 可修改值內容, 默認值 false
  enumerable : true,  // 可枚舉,默認 false
  configurable : true  // 可枚舉,默認 false
});

屬性描述符 - descriptor

屬性 說明 默認值
configurable 該屬性爲true時才能夠被刪除 false
enumerable 爲true時,能夠被for...in或Object.keys枚舉 false
value 該屬性對應的值 undefined
writable 爲true時,value才能被賦值運算符改變 false
get 取值的時候,觸發 undefined
set 修改屬性的時候,觸發 undefined

set 和 get

設置set或者get,就不能在設置value和wriable,不然會報錯。ip

let obj = {
    __age: 18
};

Object.defineProperty(obj, 'age', {
    enumerable: true,
    configurable: true,
    get: function () {
        console.log('get------------age');
        return 'My age is ' + this.__age;
    },
    set: function (newVal) {
        console.log('set------------age', newVal);
        this.__age = newVal;
    }
});

console.log(obj.__age);  // 18,  __age爲普通屬性
console.log(obj.age);  // My age is 18  , 觸發 get()
obj.age = 22;  // 觸發 set()

console.log(obj.__age);  // 22
console.log(obj.age);  // My age is 22, 觸發 get()
obj.__age = 33; // 既不觸發 set() , 也不觸發 get()

console.log(obj.__age);  // 33
console.log(obj.age);  // My age is 33 , 觸發 get()

👉 注意

1. 默認狀況下,使用 Object.defineProperty() 添加的屬性值是不可修改的

let obj = {};  
 
Object.defineProperty(obj, "age", {
  value : '18',   
});

console.log(obj.age);   // 18

obj.age = 20;

console.log(obj.age);   // 18

2. configurable 能夠看作是全部屬性描述符的總開關,一旦設置爲 false 後(若是不設置,默認值也是 false),後面全部描述符就都不能被改變了。

若是第一次不設置 configurable,或者設置爲 false, 第二次再設置 configurable, 就會報錯。get

let obj = {};  
 
Object.defineProperty(obj, "age", {
  value : '18',   
  configurable:false
});

Object.defineProperty(obj, "age", {
  value : '18',   
  configurable:true
});

// error: Uncaught TypeError: Cannot redefine property: age

3. 表格裏面的幾個描述符是不容許同時存在的

描述符殼同時具備的鍵值:it

configurable enumerable value writable get get
數據描述符 Yes Yes Yes Yes No
存取描述符 Yes Yes No No Yes

👉 若是同時設置(value或writable)和(get或set)關鍵字,將報錯。

相關文章
相關標籤/搜索