JS对象属性

ECMA-262第5版描述了对象属性的各种特征,对象的属性分为两种,数据属性和访问器属性一个属性只能是数据属性或者访问器属性中的一种)。数据属性具有4个特性(描述符),即configurable, enumerable, writable, value,访问器属性具有4个属性,configurable, enumerable, getter, setter。当调用Object.defineProperty为对象属性设置描述符时,当设置了writable或者value之后,不能再对其设置getter或者setter属性,否则会报错:

var human={
    name:"chengkang",
    _wife:"pengke"
};
Object.defineProperty(human,"height",{writable:true,value:20,get:function(params) {
    return 30;
}});

TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified

数据属性

数据属性有4个特性,configurable, enumerable, writable, value.

如下:(注意使用Object.defineProperty来创建属性时,writable, enumerable, configurable若未指定则默认为false

特性 数据类型 描述 默认值
[[Value]] 任何Javascript类型 包含这个属性的数据值。 undefined
[[Writable]] Boolean 如果该值为 false,则该属性的 [[Value]] 特性 不能被改变。 true
[[Enumerable]] Boolean 如果该值为 true,则该属性可以用 for…in 循环来枚举。 true
[[Configurable]] Boolean 如果该值为 false,则该属性不能被删除,并且 除了 [[Value]] 和 [[Writable]] 以外的特性都不能被改变。 true

var human={
    name:"ck",
    _wife:"pk"
};
human.name = "ck1n9";
Object.defineProperty(human,"height",{writable:true,value:20});
Object.defineProperty(human, "height", {
    enumerable: true,
    value: 20
});
//TypeError: can't redefine non-configurable property "height"
//可以想象,当第一次创建属性的时候指定了configurable为false的时候,想再设置其为ture就不可以了。

访问器属性

访问器属性会有一个或者两个访问器函数(get函数和set函数),明显,当只设置get函数时表示其只可读不可写,当只设置set函数时表示其只可写不可读。

特性 数据类型 描述 默认值
[[Get]] 函数对象或者 undefined 该函数使用一个空的参数列表,能够在有权访问的情况下读取属性值。 undefined
[[Set]] 函数对象或者 undefined 该函数有一个参数,用来写入属性值。 true
[[Enumerable]] Boolean 如果该值为 true,则该属性可以用 for…in 循环来枚举。 true
[[Configurable]] Boolean 如果该值为 false,则该属性不能被删除,并且 除了 [[Value]] 和 [[Writable]] 以外的特性都不能被改变。 true

可以使用两种方法为对象添加getter:

a. 在对象初始化的时候为对象指定:

var human={
    name:"ck",
    _wife:"pk",
    get myGirl() {
        return this._wife;
    }
};
console.log(human.myGirl);//pk

b. 调用Object.defineProperty来指定:


var human={
    name:"ck",
    _wife:"pk",
    _age:20,
    get myGirl() {
        return this._wife;
    }
};
Object.defineProperty(human,"age",{get:function() {
    return this._age+1;
}});
console.log(human.age);//21

c.使用计算属性名:

var prop = "age";
var students = {
    set currSt(name){
        this.sts.push(name);
    },
    sts:[],
    get [prop](){
        if(prop == "age")
          return 20;
        else if(prop == "height")
          return 180;
        else
          return undefined;
    }
};
console.log(students[prop]);//20

当你需要访问返回动态计算值的属性,或者你可能需要反映内部变量的状态,而不需要使用显式方法调用。在JavaScript中,可以使用 getter 来实现,getter创建一个伪属性类型

可以使用相同的方法来设置setter:
a. 初始化的时候指定:

var students = {
    set currSt(name){
        this.sts.push(name);
    },
    city:"chongq",
    sts:[]
};
students.currSt = "ck";
students.currSt = "pk";
console.log(students.currSt);//由于currSt是伪属性,返回undefined
console.log(students.sts.join("--"));//ck--pk

b.调用Object.defineProperty:

Object.defineProperty(students,"home",{set:function(params) {
    this.city = params;
}});
students.home = "anhui";
console.log(students.city);//anhui

c.使用计算属性名:

var expr = "foo";

var obj = {
  baz: "bar",
  set [expr](v) { this.baz = v; }
};

console.log(obj.baz); // "bar"
obj.foo = "baz";      // run the setter
console.log(obj.baz); // "baz"

你可能感兴趣的:(JavaScript)