在javaScript中,对象的属性分为两种类型:数据属性和访问器属性。
一、数据属性
数据属性:包含一个数据值的位置,在这个位置可以读取和写入值。数据属性有4个描述其行为的特性:
1、value:包含该属性的数据值,默认为undefined。
2、writable:表示能否修改属性的值。
3、enumerable:表示能否通过for-in循环返回属性。
4、configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为true。
如下面这个例子:创建一个对象person,打印出name属性的特性的默认值。
执行结果:
修改数据属性的默认特性:
修改数据属性的默认特性要用到一个方法:Object.defineProperty()方法,这个方法有三个参数:属性所在的对象,属性名,一个描述符对象。
Object.defineProperty(person,'name',{ writable:false, value:"aaa", configurable:false, enumerable:false })
二、访问器属性
1、访问器属性:这个属性不包含数据值,包含一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的。
2、访问器属性包含四个特性:
configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为false。
enumerable:表示能否通过for-in循环返回属性,默认为false。
Get:在读取属性时调用的函数,默认为undefined。
Set:在写入属性时调用的函数,默认为undefined。
注意:访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义。
var book = { _year:2020,//下划线表示内部属性,只能通过对象的方法来读写 editor:2 } console.log(book) Object.defineProperty(book,'year',{ get(){ return this._year }, //若只指定get不指定set,那就默认该属性是只读的。 set(newYear){ if(newYear !== this._year){ this._year = newYear; this.editor++; } } }) console.log(Object.getOwnPropertyDescriptor(book,'year')); console.log("未修改"+book.year); book.year = 2018; console.log('修改后year的值'+book.year); console.log('修改year的值后,editor属性的值:'+book.editor);
执行结果:
拓展:
1、Object.defineProperty()
通过Object.defineProperty() 可以直接在对象上创建一个属性,也可以修改已有的属性。
Object.defineProperty(obj, prop, descriptor) 接收三个参数:
obj:属性所在的对象
prop:要访问的属性名
descriptor:描述符对象
描述符对象包含六个属性:configurable、enumerable、writable、value、get、set ,要修改属性的特性,必须使用Object.defineProperty()方法。
通过以上两种方式添加的对象属性,其布尔值特性默认值是true,通过Object.defineProperty来修改属性特性时,只设置需要修改的特性即可;而通过Object.defineProperty创建的属性,其布尔值特性默认值是false。
2、Object.defineProperties()
通过Object.defineProperties()可以一次性为对象定义多个属性。
var person = {}; Object.defineProperties(person, { name: { value: 'Nicy', writable: true }, _age: { value: 21, enumerable: true, writable: true, configurable: true }, age: { get: function() { return this._age; }, set: function(value) { this._age = value; } } });