在新的js规范中,我们又多了几种定义属性的方法。给一个对象添加属性,以前可能是这样的
var o = {name: '未起名';}
现在可以这样子
var o = {get name(){return '终生不改名'}} o.name // 终生不改名 o.name = '换个名字'; o.name // 终生不改名;没法改变其值
还可以是这样子的
var o = {}; Object.defineProperty(o, name, { value: '数据属性', writable: true }) // witable表示该属性是否可读写。false只可读,true可读写 o.name = '可修改的属性' o.name // ?
当然还有其他的方式。
以上两种新的写法,第一种添加的属性叫做存储器属性(getter&setter),第二种是数据属性(value)。一个【属性描述符】不能同时包含value属性又有setter&getter之一。
【属性描述符】是一个对象,它是描述对象属性的。描述符一般有四个属性,分为存储器属性描述符和数据属性描述符(这个是我自己的分类)
//存储器属性描述符对象 { get: function(){}, set:function(){}, enumerable:boolean, configurable:boolean } //数据属性描述符对象 { value:'', writable:boolean, enumerable:boolean, configurable:boolean }
如果没有显式声明某属性,默认是undefined或者false。enumerable表示该属性是否可枚举。像很多内置的对象的属性一样,设为false,则此属性是不可以枚举的(for in循环无法遍
历)。configurable表示是否可配置,如是否可以用delete删除此属性,是否可以修改enumerable或者writable的值。writable是否可写,对于存储器属性,没有该项。其读写操作由get、
set完成。当然,这只是粗略的说明。
存储器属性
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可以实现很多意想不到的功能,除了保持对象属性不变,可以监听属性变化、读取(类似日志),还能像内置对象的属性一样,扩展得方法也能不被枚举出来。
浙公网安备 33010602011771号