zoukankan      html  css  js  c++  java
  • javascript对象属性——数据属性和访问器属性

          ECMA-262第五版在定义时,描述了属性property的各种特征,定义这些特性是为了实现javascript引擎用的,为了表示该特性是内部值,规范把它们放在了两对儿方括号中,例如[[Enumerable]]。我们参考第五版描述。

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

      数据属性

           数据属性包含一个数据值的位置,在这个位置可以读取和写入。该属性有4个描述其行为的特性。

           [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性特性,或者能否把属性修改为访问器属性。我们通常直接在对象上定义属性,这个特性默认值为true。

           [[Enumerable]]:表示能否通过for-in循环返回属性。我们通常直接在对象上定义的属性,默认值为true。

           [[Writable]]:表示能否修改属性的值。我们通常直接在对象上定义的属性,默认值为true。

           [[Value]]:包含这个属性的数据值。读取值从这里读,写入也把新值保存在这里。这个特性默认值为undefined。

           

           要修改属性默认的特性,必须使用ECANScript5的Object.defineProperty()方法。

           这个方法接收三个参数:属性所在对象,属性名称,一个描述符对象。

           描述符对象的属性必须是 configurable,enumerable,writable,value。设置其中一个或多个值,可以修改对应的特性。

          

     1  var person = {};
     2  
     3 Object.defineProperty(person,'name',{
     4      writable: false,
     5      value: 'jack'           
     6  });
     7  
     8 alert(person.name); // 'jack'
     9 person.name = 'Tom';
    10 alert(person.name); // 'jack'

          这个例子创建了一个person对象,并为其创建了一个name属性,它的值'jack'是只读的,不可修改的。如果尝试为它指定新值,在非严格模式下会被忽略,严格模式下,会抛出错误。

          注意:如果把configurable属性设置为false,表示无法对属性删除,重新定义,修改等。如果对这个属性调用delete,非严格模式下没什么发生,严格模式下会导致错误。而且,一旦把属性定义为不可配置,就再不能把他变回可配置了。此时在调用Object.defineProperty()方法修改除writable之外的特性,都会导致错误:

     1 var person = {};
     2 Object.defineProperty(person,'name',{
     3        configurable: false,
     4        value: 'Tom'
     5 });
     6 
     7 //抛出错误
     8 Object.definProperty(person,'name'{
     9        configurable: true,
    10        value: 'Tom'
    11 });

          访问器属性

           访问器属性不包含数据值,它们包含一对儿getter和setter函数(这两个函数都不是必须的)。

           读取调用getter,写入调用setter。

           访问器属性有如下四个特性

           [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性特性,或者能否把属性修改为访问器属性。我们通常直接在对象上定义属性,这个特性默认值为true。

           [[Enumerable]]:表示能否通过for-in循环返回属性。我们通常直接在对象上定义的属性,默认值为true。

          [[Get]]:在读取属性时调用函数。默认值为undefined。

          [[Set]]:在写入属性时调用函数。默认值为undefined。

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

     1 var book = {
     2       _year = 2004,
     3       edtion: 1
     4 }
     5 Object.defineProperty(book,'year',{
     6       get: function(){
     7              return this._year;
     8       },
     9       set: function(newValue){
    10             if(newValue > 2004){
    11                  this._year = newValue;
    12                  this.edition += newValue - 2004;
    13             }
    14       }
    15 });
    16 book.year = 2005;
    17 alert(book.edition);  // 2

          以上代码给book对象定义了两个默认属性:_year和edition。_year表示通过对象访问方法访问属性。

          而访问器属性year包含getter和setter函数。getter函数返回_year的值,setter计算正确的版本。修改year为2005会导致_year变成2005。edition变为2.这是使用访问器属性的常见方式。

          在不支持Object.defineProperty()方法的浏览器中不能修改[[Configurable]]和[[Enumerab]]。

  • 相关阅读:
    继承中类的作用域
    访问控制与继承
    虚函数与抽象基类
    定义基类和派生类
    类成员指针
    固有的不可移植特性
    局部类
    union
    嵌套类
    枚举类型
  • 原文地址:https://www.cnblogs.com/webhb/p/5614259.html
Copyright © 2011-2022 走看看