首页 > 代码库 > ECMAScript 5中属性的特性值
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);//true23 alert(b.enumerable);//true24 alert(b.writable);//true25 26 var c = Object.getOwnPropertyDescriptor(a,‘style‘);27 alert(c.configurable);//false28 alert(c.enumerable);//false29 alert(c.writable);//false30 31 var d = Object.getOwnPropertyDescriptor(a,‘country‘);32 alert(a.country);//none33 alert(d.configurable);//false34 alert(d.enumerable);//false35 alert(d.set);//undefined36 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);//car15 console.log(b.configurable);//false16 17 Object.defineProperty(a,‘type‘,{18 configurable: true19 });
上面代码在火狐的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);//car12 console.log(b.configurable);//false13 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);//to21 console.log(b.writable);//false22 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);//jiangnan12 console.log(b.configurable);//false13 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未指定,默认为undefined10 //其余两个特性默认为false11 }12 });13 console.log(a.type);//object14 var b = Object.getOwnPropertyDescriptor(a,‘name‘);15 16 console.log(b.writable);//false17 18 Object.defineProperty(a,‘name‘,{19 writable: true,20 });
运行结果:
以上就是关于对象属性特性的内容。
ECMAScript 5中属性的特性值