ECMAScript数据属性和访问器属性

来源:互联网 发布:淘宝二手苹果 编辑:程序博客网 时间:2024/05/02 01:26

ECMA-262中把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”
js中每个对象都是基于一个引用类型创建的。
创建自定义对象的最简单方式无非是创建一个object的实例,再为其添加属性和方法。
效果图
用对象字面量模式可以写成这样:
效果图
以上两种写法创建的person对象具有相同的属性和方法,这些属性在创建时都带有一些特征值,javascript通过这些特征值来定义他们的行为。

ECMA-262第五版定义了一些特性来描述属性的各种特征,这些特性是为了实现javascript引擎用的,属于内部值,因此不能直接访问他们。

ECMAScript中有两种属性:数据属性和访问器属性。

数据属性:数据属性包含一个数据值的位置,在该位置可以读取和写入值。数据属性有4个描述其行为的特性。
[[Configurable]] : 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性;
[[Enumerable]] : 表示能否通过for-in循环返回属性;
[[Writable]] : 表示能否修改属性的值;
[[Value]] : 包含这个属性的数据值,读取属性值的时候,从这个位置读,写入属性值的时候,把新值保存在这个位置。默认值为undefined。
对于上面创建的对象里定义的属性,它们的[[Configurable]]、[[Enumerable]]、[[Writable]]特性都被设置为true,而[[Value]]特性被设置为指定的值。
要修改默认的特性,必须使用ECMAScript5的Object.defineProperty()方法,该方法接收三个参数:属性所在对象、属性的名字和一个描述符对象,其中描述符对象的属性必须是:configurable、enumerable、writable、value。设置其中一个或多个,可修改对应的特性值。例如:
效果图
该例子创建了一个name的属性,设置其值“zuoran”是只读的。这个属性的值是不可修改的,如果尝试为其指定新值,在非严格模式下,赋值操作会被忽略,在严格模式下会抛出错误。
下面设置configurable(不可配置属性)的值:
效果图
这里把configurable设置为false,表示不能从对象中删除属性,如果对该属性调用delete,在非严格模式下什么也不会发生,在严格模式下会抛出错误,而且,一旦把属性的configurable设置为false,就不可能在设置为true,因为此时再调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误。
总结说可以多次调用Object.defineProperty()方法修改同一个属性,但是在把configurable特性设置为false之后就会有限制了。在调用Object.defineProperty()方法时,如果不指定,configurable、enumerable和writable特性的默认值都是false。

访问器属性:该属性不包含数据值,包含一对getter和setter函数。访问器属性有如下4个特性:
[[Configurable]] : 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性;
[[Enumerable]] : 表示能否通过for-in循环返回属性;
[[Get]] : 在读取属性时调用的函数,默认值是undefined;
[[Set]] : 再写入属性时调用的函数,默认值是undefined。
要定义访问器属性必须使用Object.defineProperty()方法,例如:
效果图
这是使用访问器属性的常用方式,即设置一个属性的值导致其他属性发生变化。不一定非要同时指定两个属性,只指定getter意味着属性不能写,只指定setter意味着属性不能读。如下:
效果图
在非严格模式下不会发生什么,在严格模式下会抛出错误:
效果图
效果图

ECMAScript5还定义了一个Object.defineProperties()方法,用于定义多个属性,该方法接收两个对象参数,如下调用:
效果图

ECMAScript5的Object.getOwnPropertyDescriptor()方法可以读取属性的特性。该方法接收两个参数:属性所在对象和要读取其描述符的属性名称,返回值是一个对象,若是数据属性,即为之前数据属性对应的4个特性,若是访问器属性,即为之前访问器属性对应的4个特性。例如(对应上面定义的多个属性):
效果图

以上参考《JavaScript高级程序设计(第3版)》。

0 0
原创粉丝点击