zoukankan      html  css  js  c++  java
  • 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  });

    运行结果:

    以上就是关于对象属性特性的内容。

  • 相关阅读:
    UVA 254 Towers of Hanoi
    UVA 701 The Archeologists' Dilemma
    UVA 185 Roman Numerals
    UVA 10994 Simple Addition
    UVA 10570 Meeting with Aliens
    UVA 306 Cipher
    UVA 10160 Servicing Stations
    UVA 317 Hexagon
    UVA 10123 No Tipping
    UVA 696 How Many Knights
  • 原文地址:https://www.cnblogs.com/fogwind/p/5931861.html
Copyright © 2011-2022 走看看