对象属性

创建对象

var a1 = new Object();
a1.name = "a1";
a1.age = 20;
a1.job = 'IT';
a1.sayName = function(){
    console.log(this.name);
};

var a2 = {
   name:'a2',
   age:20,
   job:'IT',
   sayName:function(){
       console.log(this.name);
   }
};

数据属性

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

  • Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • Enumerable:表示能否通过for-in循环 返回属性,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • Writable:表示能否修改属性的值,像上面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • Value:包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置,这个特性的默认值为undefined。

在上面的例子中,都含有一个名为age的属性,并为它指定的值是20,也就是说[[Value]]特性被设置为20,而对这个值的任何修改都将反映在这个位置,要修改属性默认的特性,必须使用Object。defineProperty()方法,这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符(descriptor)对象。其中,描述符对象的属性必须是:configurable,enumerable,writable和value。设置其中的一个或多个值,可以修改对应的特性值。

var b = {};
Object.defineProperty(b,'name',{
    writable:false,
    value:'Nicholas'
});
console.log(b.name);   //Nicholas
b.name = "Greg";
console.log(b.name);   //Nicholas

上面的例子中创建了一个name属性,他的属性值“Nicholas”是只读的,这个属性的值是不可修改的,如果尝试修改,在非严格模式下,赋值操作将被忽略,在严格模式下,赋值操作会导致抛出错误。类似的规则也适用于不可配置的属性。

var c = {};
Object.defineProperty(c,'name',{
    configurable:false,
    value:'Nicholas'
});
console.log(c.name);   //Nicholas
delete c.name;
console.log(c.name);   //Nicholas

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

var d = {};
    Object.defineProperty(d,'name',{
    configurable:false,
    value:'Nicholas'
});
Object.defineProperty(d,'name',{  //Uncaught TypeError: Cannot redefine property: name
    configurable:true,
    value:'Nicholas'
});

也就是说,可以多次调用Object.defineProperty()方法修改同一个属性,但在把configurable特性设置为false之后就会有限制了。
 在调用Object.defineProperty()方法时,如果不指定,configurable,enumerable和writable特性的默认值都是false。

访问器属性

访问器属性不包含数据值,由一对getter和setter函数(均非必须)构成,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下4个特性:

  • configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性,对于直接在对象上定义的属性,这个特性的默认值为true。
  • enumerable:表示能否通过for-in循环返回属性。对于直接在对象上定义的属性,这个特性的默认值为true。
  • get:在读取属性时调用的函数,默认值为undefined。
  • set:在写入属性时调用的函数,默认值为undefined。

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

var e = {
    _year:2016,
    edition:1
};
Object.defineProperty(e,"year",{
    get:function(){
      return this._year;
    },
    set:function(newValue){
        if(newValue > 2016){
            this._year = newValue;
            this.edition += newValue - 2016;
        }
     }
});
c.year = 2018;
console.log(c.edition);  //3

上面的例子中创建了一个对象,并给它定义了两个默认的属性:_year和edition。_year前面的下划线是一个记号,用于表示只能通过对象方法访问的属性,而访问器属性year则包含一个getter函数和一个setter函数。getter函数返回_year的值,setter函数通过计算来确定正确的版本,因此把year属性修改为2018会导致_year变成2018,而edition变为3,这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。

不一定非要同时指定getter和setter,只指定getter以为着属性是不能写,尝试写入属性会被忽略。在严格模式下,尝试写入只指定了getter函数的属性会抛出错误。类似低,没有指定setter函数的属性也不能读,否则在非严格模式下会返回undefined,而在严格模式下会抛出错误。

猜你喜欢

转载自www.cnblogs.com/yuyujuan/p/9169059.html
今日推荐