在新的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能够实现不少意想不到的功能,除了保持对象属性不变,能够监听属性变化、读取(相似日志),还能像内置对象的属性同样,扩展得方法也能不被枚举出来。