本文摘自PHP中文网,作者青灯夜游,侵删。
创建对象的方式有两种:第一种,通过new操作符后面跟Object构造函数,第二种,对象字面量方式。如下
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
这两种方式创建出来的对象是一样的,有相同的属性和方法。这些属性内部都有描述其行为的属性描述符。
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。
ECMAScript中属性分为两种:数据属性和访问器属性。
数据属性
数据属性包含四个属性描述符:
[[Configurable]] : 表示能否通过delete删除属性从而重新定义属性,能否修改属性特性,能否把属性修改为访问器属性。通过以上方式添加的对象属性,默认为true。
[[Enumerable]] : 表示能否通过for-in 循环访问属性。通过以上方式添加的对象属性,默认为true。
[[Writable]] : 表示能否修改属性的值。通过以上方式添加的对象属性,默认为true。
[[Value]] : 包含这个属性的数据值,可读取写入。通过以上方式添加的对象属性,默认为undefined。
Writable
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Object.defineProperty直接创建的属性writable默认为false,value值不可修改,此时修改name为Lee,在非严格模式下不会报错,但操作被忽略,在严格模式下会报错。
Configurable
1 |
|
总结一下configurable:当configurable设为false时,
1、不可以通过delete去删除该属性从而重新定义属性;
2、不可以转化为访问器属性;
3、configurable和enumerable不可被修改;
4、writable可单向修改为false,但不可以由false改为true;
5、value是否可修改根据writable而定。
当configurable为false时,用delete删除该属性,在非严格模式下,不会报错,但操作被忽略,在严格模式下会报错;其他不可被修改的特性修改时会报错。
Enumerable
enumerable表示对象属性是否可以在for...in和Object.keys()中被枚举。
1 2 3 4 5 6 7 8 9 10 11 |
|
访问器属性
访问器属性包含四个属性描述符:
[[Configurable]] : 表示能否通过delete删除属性从而重新定义属性,能否修改属性特性,能否把属性修改为数据属性。直接在对象上定义的属性,默认为true。
[[Enumerable]] : 表示能否通过for-in 循环访问属性。直接在对象上定义的属性,默认为true。
[[Get]] : 读取属性时调用的函数,默认为undefined。
[[Set]] : 写入属性时调用的函数,默认为undefined。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
用Object.defineProperty()定义的访问器属性,其configurable和enumerable默认为false。
数据属性与访问器属性的相互转换
Object.getOwnPropertyDescriptor 读取属性的特性
使用Object.getOwnPropertyDescriptor可以获取到属性的描述符:
Object.getOwnPropertyDescriptor(obj, prop)
obj:属性所在的对象;
prop:要访问的属性名。
数据属性 -> 访问器属性
属性的特性只能是访问器描述符和数据描述符中的一种,给已有的数据属性加get或set转换为访问器属性时,其属性的value、writable就会被废弃。
如下代码,将对象原有的数据属性year转换为访问器属性:
*注:在访问器属性的get和set中,不可以使用this访问属性本身,否则会无限递归而导致内存泄漏。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
在原有的数据属性year中,使用Object.defineProperty()为属性设置get 或 set,都可以将其转换为访问器属性。
访问器属性 -> 数据属性
将访问器属性转换为数据属性,只需要给现有访问器属性设置value或writable这两个属性描述符中的任意一个即可,其原有的get和set就会被废弃,从而转换为数据属性。
上面为person定义的访问器属性age,通过Object.defineProperty()只设置了get和set,所以configurable默认为false,不可以将其转换为数据属性。可以在访问器属性和数据属性间相互转化的属性其configurable特性值必须为true。
如下代码,我们为person新定义一个访问器属性job,将其configurable设置为true ,并将其转换为数据属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
数据描述符value、writable 和访问器描述符get、set不能同时设置,否则会报错。
Object.defineProperties()
通过Object.defineProperties()可以一次性为对象定义多个属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
相关教程推荐:JavaScript视频教程
以上就是详解javascript对象的数据属性与访问器属性的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
更多相关阅读请进入《javascript》频道 >>
Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者