Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性, 并返回這個對象。
該方法允許精確添加或修改對象的屬性。通過賦值來添加的普通屬性會創(chuàng)建在屬性枚舉期間顯示的屬性(for...in 或 Object.keys 方法), 這些值可以被改變,也可以被刪除。這種方法允許這些額外的細節(jié)從默認值改變。默認情況下,使用 Object.defineProperty() 添加的屬性值是不可變的。
語法
Object.defineProperty(obj, prop, descriptor)
- obj:要在其上定義屬性的對象。
- prop:要定義或修改的屬性的名稱。
- descriptor:將被定義或修改的屬性描述符。
- 返回值:被傳遞給函數(shù)的對象。
在ES6中,由于 Symbol類型 的特殊性,用 Symbol類型 的值來做對象的key與常規(guī)的定義或修改不同,而Object.defineProperty 是定義 key為 Symbol 的屬性的方法之一。
屬性描述符
對象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符。
- 數(shù)據(jù)描述符是一個具有值的屬性,該值可能是可寫的,也可能不是可寫的。
- 存取描述符是由 getter-setter 函數(shù)對描述的屬性。
描述符必須是這兩種形式之一;不能同時是兩者。
數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:
configurable
當且僅當該屬性的 configurable 為 true 時,該屬性描述符才能夠被改變,同時該屬性也能從對應(yīng)的對象上被刪除。默認為 false。
enumerable
enumerable定義了對象的屬性是否可以在 for...in 循環(huán)和 Object.keys() 中被枚舉。
當且僅當該屬性的 enumerable 為 true 時,該屬性才能夠出現(xiàn)在對象的枚舉屬性中。默認為 false。
數(shù)據(jù)描述符同時具有以下可選鍵值:
value
該屬性對應(yīng)的值??梢允侨魏斡行У?JavaScript 值(數(shù)值,對象,函數(shù)等)。默認為 undefined。
writable
當且僅當該屬性的 writable 為 true 時,value 才能被賦值運算符改變。默認為 false。
存取描述符同時具有以下可選鍵值:
get
一個給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。該方法返回值被用作屬性值。默認為 undefined。
set
一個給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認為 undefined。
如果一個描述符不具有value,writable,get 和 set 任意一個關(guān)鍵字,那么它將被認為是一個數(shù)據(jù)描述符。如果一個描述符同時有(value或writable)和(get或set)關(guān)鍵字,將會產(chǎn)生一個異常。
let Person = {}
Person.sex = "男";
let temp = null
let p = Object.defineProperty(Person, 'name', {
get: function () {
return temp
},
set: function (val) {
temp = val
},
// value:"carl", 不可與下面的get,set并存
configurable:false,
enumerable:true
});
console.log(Object.keys(Person));