ECMAScript 5中属性的特性值
Posted Fogwind
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ECMAScript 5中属性的特性值相关的知识,希望对你有一定的参考价值。
这是《javascript高级程序设计(第三版)》第六章相关内容的总结。
ECMAScript中有两种属性:数据属性和访问器属性。每种属性都有四个特性值。
数据属性的四个特性值:
[[Configurable]]:表示能否通过delete删除属性;能否修改属性的特性值;能否把属性修改为访问器属性。直接在对象上定义的属性,该特性的默认值为true。
[[Enumerable]]:表示能否通过for-in循环返回属性。直接在对象上定义的属性,该特性的默认值为true。
[[Writable]]:表示能否修改属性的值。直接在对象上定义的属性,该特性的默认值为true。
[[Value]]:包含这个属性的数据值。读取属性值的时候。从这个位置读;写入属性值的时候,把新值保存在这个位置。该特性的默认值为undefined。
访问器属性的四个特性:
访问器属性只能通过相应的方法设置,不能在对象上直接设置。
[[Configurable]]:表示能否通过delete删除属性;能否修改属性的特性值;能否把属性修改为数据属性。
[[Enumerable]]:表示能否通过for-in循环返回属性。
[[Get]]:在读取属性时调用的函数。该特性的默认值为undefined。
[[Set]]:在写入属性时调用的函数。该特性的默认值为undefined。
ECMAScript 5中操作属性特性的方法有3个:
Object.defineProperty():该方法用来设置单个属性的特性。它接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中描述符对象的属性必须是:configurable、enumerable、writable、value、get、set中的一个或多个。当然要根据属性类型选择。
Object.defineProperties():这个方法是上一个方法的增强版,可以同时设置多个属性的特性。它接收两个对象参数:第一个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应(通过例子看,一目了然)。
Object.getOwnPropertyDescriptor():这个方法返回一个描述符对象,可以取得给定属性的特性的值。它接收两个参数:属性所在的对象和要读取其特性的属性名称。如果是数据属性,返回的对象有configurable、enumerable、writable、value四个属性;如果是访问器属性,返回的对象有configurable、enumerable、get、set四个属性。
例1
1 <script type="text/javascript"> 2 var a = { 3 name: \'A\', 4 type: \'object\' 5 } 6 //修改直接在对象上定义的属性的值 7 Object.defineProperty(a,\'type\',{ 8 value: \'car\' 9 }); 10 //用Object.defineProperty()方法给对象添加属性 11 Object.defineProperty(a,\'style\',{ 12 value: \'no\' 13 }); 14 //设置访问器属性 15 Object.defineProperty(a,\'country\',{ 16 get: function() { 17 return \'none\'; 18 } 19 }); 20 21 var b = Object.getOwnPropertyDescriptor(a,\'type\'); 22 alert(b.configurable);//true 23 alert(b.enumerable);//true 24 alert(b.writable);//true 25 26 var c = Object.getOwnPropertyDescriptor(a,\'style\'); 27 alert(c.configurable);//false 28 alert(c.enumerable);//false 29 alert(c.writable);//false 30 31 var d = Object.getOwnPropertyDescriptor(a,\'country\'); 32 alert(a.country);//none 33 alert(d.configurable);//false 34 alert(d.enumerable);//false 35 alert(d.set);//undefined 36 alert(d.get);//输出get后面完整的匿名函数 37 </script>
通过上面的例子可以看到,用Object.defineProperty()方法给对象添加新属性,该属性的未指定的特性值要么默认为false,要么默认(set)为undefined,说明用Object.defineProperty()方法添加的新属性除非明确设置,否则一旦设置完成后是不可配置和更改的。而原本直接定义在对象上的属性,用Object.defineProperty()方法修改,未指定的特性值仍然默认为true,还是可以配置和更改的。
例2
1 var a = { 2 name: \'A\', 3 type: \'object\' 4 } 5 //修改直接在对象上定义的属性的值 6 Object.defineProperty(a,\'type\',{ 7 configurable: false, 8 value: \'car\' 9 }); 10 11 delete a.type; 12 var b = Object.getOwnPropertyDescriptor(a,\'type\'); 13 14 console.log(a.type);//car 15 console.log(b.configurable);//false 16 17 Object.defineProperty(a,\'type\',{ 18 configurable: true 19 });
上面代码在火狐的Firebug中会报错:
意思就是说,一旦把configurable设置为false,就改不回来了。书上说,此时再调用Object.defineProperty()方法修改除writable的特性,都会导致错误。但是,我觉得这要根据这个属性是怎么添加到对象上的来区分。
先看直接在对象上直接定义的属性:
1 var a = { 2 name: \'A\', 3 type: \'object\' 4 } 5 //修改直接在对象上定义的属性的值 6 Object.defineProperty(a,\'type\',{ 7 configurable: false, 8 value: \'car\' 9 }); 10 11 console.log(a.type);//car 12 console.log(b.configurable);//false 13 14 Object.defineProperty(a,\'type\',{ 15 writable: false, 16 value: \'to\' 17 }); 18 19 var b = Object.getOwnPropertyDescriptor(a,\'type\'); 20 console.log(b.value);//to 21 console.log(b.writable);//false 22 console.log(a.type);//to
输出结果:
再调用Object.defineProperty()方法修改除writable的特性(这里修改了value的值),没有导致错误,而且还修改成功了(当然修改enumerable的值还是会导致错误的)。
再来看通过调用Object.defineProperty()方法添加的属性:
1 var a = { 2 name: \'A\', 3 type: \'object\' 4 } 5 //修改直接在对象上定义的属性的值 6 Object.defineProperty(a,\'style\',{ 7 configurable: false, 8 value: \'jiangnan\' 9 }); 10 var b = Object.getOwnPropertyDescriptor(a,\'style\'); 11 console.log(a.style);//jiangnan 12 console.log(b.configurable);//false 13 14 Object.defineProperty(a,\'style\',{ 15 writable: true, 16 value: \'to\' 17 });
看运行结果:
再调用Object.defineProperty()方法修改writable的特性,导致错误。
下面看Object.defineProperties()方法的用法:
1 var a = {}; 2 Object.defineProperties(a,{ 3 name: { 4 value: \'A\' 5 //其余的三个特性未明确指定,默认值为false 6 }, 7 type: { 8 get: function() {return \'object\'} 9 //set未指定,默认为undefined 10 //其余两个特性默认为false 11 } 12 }); 13 console.log(a.type);//object 14 var b = Object.getOwnPropertyDescriptor(a,\'name\'); 15 16 console.log(b.writable);//false 17 18 Object.defineProperty(a,\'name\',{ 19 writable: true, 20 });
运行结果:
以上就是关于对象属性特性的内容。
以上是关于ECMAScript 5中属性的特性值的主要内容,如果未能解决你的问题,请参考以下文章