JS 对象(3)—属性类型


属性类型

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

 

数据属性

数据属性包含一个数据值的位置;在这个位置可以读取和写入值。

数据属性具有4个描述其行为的特性:

 

[[Configurable]]

表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。

直接在对象上定义的属性,默认为true。

 

[[Enumerable]]

表示能否通过for-in循环返回属性。

直接在对象上定义的属性,默认为true。

除了for-in循环之外,ECMAScript5定义了两个用以枚举属性名称的函数。

Object.keys()返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。

其工作原理类似这样:

 1 function keys(object) {
 2     if(typeof object !== "object") {
 3         throw TypeError;    //参数必须是对象
 4     };
 5     var result = [];    //创建一个数组,用以保存枚举的属性
 6     for (prop in object) {    //遍历所有可枚举的属性
 7         if (object.hasOwnProperty(prop)) {    //判断是否为自有属性
 8             result.push(prop);    //将属性名添加到数组
 9         };
10     };
11     return result;    //返回数组
12 };

 

Object.getOwnPropertyNames()返回对象的所有自有属性的名称,而不仅限于可枚举的属性。

 

[[Writable]]

表示能否修改属性的值。

直接在对象上定义的属性,默认为true。

 

[[Value]]

包含这个属性的数据值;读取属性值的时候,从这个位置读取;写入属性值的时候,把值保存在这里。

这个特性默认为undefined。

 

访问器属性

访问器属性包含一对getter和setter方法。

如果属性同时具有getter和setter方法,那么它就是一个读/写属性;如果只有getter方法,则为只读属性;同理,如果只有setter方法,则为只写属性。

访问器属性有如下4个特性:

 

[[Configurable]]

表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为数据属性。

直接在对象上定义的属性,默认为true。

 

[[Enumerable]]

表示能否通过for-in循环返回属性。

直接在对象上定义的属性,默认为true。

 

[[Get]]

在读取属性时调用的函数;默认值为undefined。

在读取访问器属性时,会调用gette方法,这个函数负责返回有效的值。

 

[[Set]]

在写入属性时调用的函数;默认值为undefined。

在写入访问器属性时,会调用setter方法并传入新值,这个函数负责决定如何处理数据。

访问器属性不能直接定义,必须使用Object.defineProperties()方法来定义。

 

定义多个属性

要修改数据属性默认的特性,必须使用ECMAScript5中的Object.defineProperty()方法;接受三个参数:属性所在的对象、属性的名字、描述符对象;其中,数据属性描述符对象的属性必须是:configurable、enumerable、writable、value;访问器属性的描述符对象的属性有configurable、enumerable、get、set。设置其中的一个或多个值,可以修改对应的特性值。

1 var person = {};
2 Object.defineProperty(person, "name", {
3     writable: false,
4     value: "CC"
5 });
6 alert(person.name);    //"CC"
7 person.name = "VV";
8 alert(person.name);    //"CC"

在调用Object.defineProperty()方法新建属性时,如果不指定,configurable、enumerable、writable特性的值都是false。

注意:使用Object.defineProperty()方法,要么修改已有属性,要么新建自有属性,不能修改继承属性。

 

Object.defineProperties()方法,通过描述符一次性定义多个属性;

接收两个对象参数:第一个对象是要添加或修改其属性的对象;第二个对象的属性与第一个对象中要添加或修改的属性一一对应。

 1 var person = {};
 2 Object.defineProperties(person, {
 3     name: {
 4         value: "CC",
 5         writable: true
 6     },
 7     age: {
 8         value: 23,
 9         writable: false
10     }
11 });
12 alert(person.name);    //"CC"
13 person.name = "VV";
14 alert(person.name);    //"VV"

 

读取属性的特性

Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符;

接收两个参数:属性所在的对象,要读取其描述符的属性名称。

返回值是一个对象;如果是数据属性,这个对象的属性有configurable、enumerable、writable、value;如果是访问器属性,这个对象的属性有configurable、enumerable、get、set。

 1 var person = {};
 2 Object.defineProperties(person, {
 3     name: {
 4         value: "CC",
 5         writable: true
 6     },
 7     age: {
 8         value: 23,
 9         writable: false
10     }
11 });
12 var descriptor = Object.getOwnPropertyDescriptor(person, "name");
13 alert(descriptor.value);       //"CC"
14 alert(descriptor.writable);    //true

 

注意:

Object.getOwnPropertyDescriptor()方法,只能用于实例属性;如果要取得原型属性的描述符,必须直接在原型对象上调用Object.getOwnPropertyDescriptor()方法。

《JS权威指南》——Object.getOwnPropertyDescriptor()方法只能取得自有属性的描述符,要想获得继承的属性,必须遍历原型链。

 

属性的特性规则

如果对象是不可扩展的,则可以编辑已有的自有属性,但不能添加新属性;

如果属性是不可配置的,则不能修改它的可配置性和可枚举性(一旦将confidurable特性改为false,不能再改回true);

如果访问器属性是不可配置的,则不能修改其getter和setter方法,也不能将其转换为数据类型;

如果数据属性是不可配置的,则不能将它的writable特性从false改为true,但可以从true改为false;也不能将其转换为访问器属性;

如果数据属性是不可配置且不可写的,则不能修改它的value值;然而可配置但不可写的value值是可以修改的(实际上是先标记为可写的,然后修改value值,最后转换为不可写的)。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM