在介绍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的属性赋值,都会报错。