javascript存储器属性与数据属性

在新的js规范中,咱们又多了几种定义属性的方法。给一个对象添加属性,之前多是这样的函数

var o = {name: '未起名';}

如今能够这样子this

var o = {get name(){return '终生不更名'}}

o.name // 终生不更名

o.name = '换个名字';

o.name // 终生不更名;无法改变其值

还能够是这样子的spa

var o = {};
Object.defineProperty(o, name, {
    value: '数据属性',
    writable: true
})
// witable表示该属性是否可读写。false只可读,true可读写
o.name = '可修改的属性'

o.name // ?

固然还有其余的方式。日志

以上两种新的写法,第一种添加的属性叫作存储器属性(getter&setter),第二种是数据属性(value)。一个【属性描述符】不能同时包含value属性又有setter&getter之一。code

【属性描述符】是一个对象,它是描述对象属性的。描述符通常有四个属性,分为存储器属性描述符和数据属性描述符(这个是我本身的分类)对象

//存储器属性描述符对象
{
    get: function(){},
    set:function(){},
    enumerable:boolean,
    configurable:boolean
}

//数据属性描述符对象
{
    value:'',
    writable:boolean,
    enumerable:boolean,
    configurable:boolean
}

若是没有显式声明某属性,默认是undefined或者false。enumerable表示该属性是否可枚举。像不少内置的对象的属性同样,设为false,则此属性是不能够枚举的(for in循环没法遍blog

历)。configurable表示是否可配置,如是否能够用delete删除此属性,是否能够修改enumerable或者writable的值。writable是否可写,对于存储器属性,没有该项。其读写操做由get、递归

set完成。固然,这只是粗略的说明。ip

存储器属性get

var name = '给孩子起个名吧',

person = {
    // 读取属性
    get childName(){
        return name;
    },
    // 给属性写入值
    set childName(newName){
        name = newName;
    },
    // 是否可枚举
    enumerable: true,
   // 是否可配置
    configurable: true
}
// 上面这几行代码近似于下面的效果

/*
var person = {childName: name};
*/
/*这种写法须要借助第三个变量或者属性来完成。由于在get和set使用【this.该属性】会形成无限递归,没法在set中没法给
该属性赋值,也没法在get中返回。要么借助第三者(get&set),要么返回常量(get)
*/
//一个能够读取,但不容许改变的值.例如产品的ID号,一旦生产,则不容许再修改
var product = {get pID(){return '113230'}}
product.pID = '231234' //1.0。企图改变pID的值是徒劳的

 数据属性

/* 数据属性不能像存储器属性那样直接在对象内部声明,否则会变成普通属性。
须要借助defineProperty来完成*/
var o = {};
//defineProperty接受三个参数,对象,对象的属性名,属性描述符(也是对象)
Object.defineProperty(o,'name',{
    value: '这是数据属性',//这个值也能够是个函数,调用:o.name()
    writable: true,
    enumerable: true,
    configurable: true
});

o.name // 这是数据属性

//存储器属性也能够用这种方式(添加多个属性用defineProperties),给一个矩形rect添加三个属性,w,h,area

var rect = {};
Object.defineProperties(rect, {
    w:{value:10,writable:true},
h:{value:15,writable:true},
area: {
get: function(){
return this.w*this.h;
},
set: function(newVal){
var rat = newVal/this.area;
this.w *= rat;
this.h *= rat;
}
}
});
rect.area // 150
rect.area *= 2;
//改变面积的值,间接改变长和宽
rect.w // 20
rect.h // 30

总结:利用这些API能够实现不少意想不到的功能,除了保持对象属性不变,能够监听属性变化、读取(相似日志),还能像内置对象的属性同样,扩展得方法也能不被枚举出来。

更多相关阅读或者这里

相关文章
相关标签/搜索