在介紹js中Object.defineProperty()和defineProperties()以前,咱們瞭解下js中對象兩種屬性的類型:數據屬性和訪問器屬性。
數據屬性
數據屬性包含一個數據的位置,在這個位置能夠讀取和寫入。其有4個描述其行爲的特性
[[Configurable]]
表示可否經過delete刪除屬性從而從新定義屬性,可否修改屬性的特性,可否把屬性修改成訪問器屬性。經過對象字面量建立的屬性,默認爲true
[[Enumerable]]
表示可否經過for-in循環訪問屬性。(或經過Object.keys()獲取)。默認爲true
[[Writable]]
表示可否修改屬性值。默認爲true.
[[Value]]
包含這個屬性的數據值。屬性值的讀寫都在這個位置。默認爲undefined
訪問器屬性
訪問器屬性不包含數據值,它們包含一對getter和setter函數(非必須),getter負責讀取屬性時調用並返回有效值;setter是寫入屬性時調用並負責如何處理該數據。其也有4個特性
[[Configurable]]
表示可否經過delete刪除屬性從而從新定義屬性,可否修改屬性的特性,可否把屬性修改成數據屬性。默認爲true
[[Enumerable]]
表示可否經過for-in循環返回屬性。默認爲true
[[Get]]
在讀取屬性時調用的函數。默認爲undefined
[[Set]]
在寫入屬性時調用的函數。默認爲undefined
訪問器屬性不能直接定義,必須使用Object.defineProperty();
屬性的定義:在js中,給一個對象添加方法很簡單,如
var obj = {};
obj.name = 'lc';
obj.weight = 180;
但,這裏咱們介紹另一種兩種方式:
Object.defineProperty()
功能:方法會在對象上定義一個新屬性,或者修改一個對象的現有屬性,比返回這個對象。若是不指定configurable、enumerable、writable,則默認值爲false;不指定value、get、set,則默認爲undefined
語法:Object.defineProperty(obj,prop,descriptor)
obj:須要修改的對象。
prop:目標對象須要定義或修改的屬性名稱
descriptor:將被定義或修改的屬性描述符
var book = {
// _price: 20
};
//添加name屬性
Object.defineProperty(book, 'name', {
value: 'bkk',
enumerable: true,
configurable: false,
writable: true
});
console.log(book.name) //bkk
Object.defineProperties()
功能:方法將直接在對象上定義一個或多個新的屬性或修改現有屬性,並返回該對象
語法:Object.defineProperties(obj,props)
obj:將要被添加屬性或修改屬性的對象
props:該對象的一個或多個鍵值對定義了將要添加或修改的屬性的具體配置。
Object.defineProperties(book,{
test:{},
_year:{
value:2004,
writable: true,
enumerable:true
},edition:{
value:1,
writable: true
},year:{ //定義訪問器屬性
get :function(){
return this._year;
},
set: function(newValue){
if(newValue>2004){
this._year = newValue;
this.edition += newValue -2004;
}
}
}
})
Object.getOwnPropertyDescriptor()
功能:獲取對象自身屬性的描述符
語法:Object.getOwnPropertyDescriptor(obj,prop);
obj:須要查找的目標對象
prop:須要查找的屬性名
var desc = Object.getOwnPropertyDescriptor(book,'name');
console.log(desc);
//{value: "bkk", writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptors()
功能:獲取對象自身全部屬性的描述符
語法:Object.getOwnPropertyDescriptors(obj);
obj:須要查找的目標對象
var descs = Object.getOwnPropertyDescriptors(book);
console.log(descs);
{
"name":{
"value":"bkk",
"writable":true,
"enumerable":true,
"configurable":false
},
"test":{
"writable":false,
"enumerable":false,
"configurable":false
},
...
"year":{
"enumerable":false,
"configurable":false
}
}
回到開定用對象字面量定義的對象 obj
var descs = Object.getOwnPropertyDescriptors(obj);
console.log(JSON.stringify(descs))
{
"name":{
"value":"lc",
"writable":true,
"enumerable":true,
"configurable":true
},
"weight":{
"value":180,
"writable":true,
"enumerable":true,
"configurable":true
}
}
能夠看到writable、enumerable、configurable的默認值都是true.
-----------------------------------------------------------------------------------------------
在嚴格模式下,刪除一個configurable=false屬性,或給一個writable=false的屬性賦值,都會報錯。