Javascript中Object.defineProperty學習筆記

通過Object.defineProperty()我們可以給Object對象定義屬性,同時還能更細粒度的控制該屬性。

基本語法:

Object.defineProperty(obj, prop, descriptor)

參數(shù):

  • obj是要定義屬性的對象
  • prop是要定義的屬性的名稱或Symbol
  • descriptor是定義屬性的描述符,描述符有兩種形式,數(shù)據(jù)描述符和存取描述符

返回值:返回第一個參數(shù)obj

數(shù)據(jù)描述符是一個具有值的屬性,該值可以是可寫的,也可以是不可寫的。存取描述符是由 getter 函數(shù)和 setter 函數(shù)所描述的屬性。一個描述符只能是這兩者其中之一,但兩個不能同時使用。

上手

var obj = {};
Object.defineProperty(obj, 'foo', {    
    value: 'hello',    
    writable: true
});
console.log(obj); // {foo: "hello"}
 
Object.defineProperty(obj, 'bar', {
    get: function() {
        return 'world';
    }
})
console.log(obj.bar);  // world

上面代碼我們分別使用了不同的描述符定義屬性,用起來就是這么簡單,描述符中我們還能配置屬性的其他選項,其中兩個描述符共享configurableenumerable選項:

  • configurable:當為true時,屬性的描述符才能夠被更改,同時該屬性也能被刪除,默認false
  • enumerable:當為true時,屬性才能被枚舉到,默認false

數(shù)據(jù)描述符有valuewritable選項:

  • value:該屬性對應的值,可以是數(shù)值,對象,函數(shù)等,默認undefined,只能用于數(shù)據(jù)描述符
  • writable:當為true時,才能使用賦值操作改變上面value的值,默認false

存取描述符有getset選項:

  • get:是一個無參的getter函數(shù),訪問該屬性時會調(diào)用這個函數(shù),并且會傳入this對象,函數(shù)的返回值作為屬性值,如果沒有get,就會返回undefined
  • set:當修改屬性值時,這個函數(shù)會被調(diào)用,并且新的值會被作為參數(shù)傳進來,同時this對象指向被賦值的對象

匯總?cè)缦拢?/p>

描述符不能混用,即一個描述符同時擁有valuewritablegetset 選項,否則會產(chǎn)生一個異常:

var obj = {};
Object.defineProperty(obj, 'bar', {
    value: 'hello',
    get: function() {
        return 'world';
    }
});
 
Uncaught TypeError: Invalid property descriptor. 
Cannot both specify accessors and a value or writable attribute

我們通過幾個例子看看enumerable在不同枚舉方法中的表現(xiàn):

var obj = {}
Object.defineProperty(obj, 'a', {
  value: 1,
  enumerable: true
});
 
Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});
 
Object.defineProperty(obj, 'c', {
  value: 3, // enumerable默認為false
}); 
 
obj.d = 4 // enumerable默認為true
 
Object.defineProperty(obj, Symbol.for('e'), {
  value: 5,
  enumerable: true
});
Object.defineProperty(obj, Symbol.for('f'), {
  value: 6,
  enumerable: false
});

for…in中:

for (var i in obj) {
    console.log(i);  // a, d
}

屬性名是symbol的不能被打印出來,enumerable是false也無法打印

Object.keys()中:

Object.keys(obj);  // ["a", "d"]

和上面一樣

展開操作符…中:

var foo = {...obj}
console.log(foo);  // {a: 1, d: 4, Symbol(e): 5}

enumerable為true的都能被解構出來,symbol也可以

通過點操作符和Object.defineProperty()添加屬性有什么區(qū)別:

var obj = {}
obj.foo = 2
// 等價于
Object.defineProperty(obj, 'foo', {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true
});

參考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容