一、 Object.defineProprty概念:
Object.defineProperty()方法会直接在一个对象上定义一个新属性,
或者修改一个对象的现有属性,并返回此对象。
二、 语法:
Object.definePrototype(obj,prop,descriptor)
- obj:要定义属性的对象。
- prop:要定义或修改的属性的名称。
- descriptor:要定义或修改的属性描述符。
返回值:被传递给函数的对象。
三、描述:
此方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,可以改变这些属性值,也可以删除这些属性值。默认情况下使用此方法添加的属性值是不可修改的。
对象里目前存在的属性描述符有两种主要形式:
-
数据描述符:是一个具有值的属性,该值可以是可写的,也可以是不可写的。
configurable:是否可以重新定义,当且仅当该属性键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。
enumerable: 是否可以枚举,当且仅当该属性键值为true时,该属性才会出现在对象的枚举属性中。默认为false。
value:该属性对应的值。默认为undefined。
writable: 是否可以修改属性值,当且仅当该属性的键值为true时,上面的value才能被赋值运算符改变,默认为false。
-
存取描述符:由getter函数和setter函数所描述的属性还可以具有以下可选键。
get :属性的getter函数,如果没有getter,则为undefined。动态计算得到当前属性值 (回调函数)。默认为undefined,当访问该属性时,会调用此函数。
set :监视当前属性值的变化,更新其他相关的属性(回调函数)。当属性值被修改时,会调用此函数。默认为undefined。
注:一个描述符只能是这两者其中之一,不能同时是两者。
这两种描述符都是对象,
描述符可拥有的键值:
configurable | enumerable | value | writable | get | set | |
---|---|---|---|---|---|---|
数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
如果一个描述符不具有value、writable 、get、set中任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有value或writable和get或set键则会出现异常。
四、代码演示:
创建属性:
// 创建属性
var o = {
};
Object.defineProperty(o,"a",{
value:37,
writable:true,
enumerable:true,
configurable:true
});
//对象o拥有了属性a,值为37
//在对象中添加一个设置了存取描述符属性的示例
var Bvalue = 38;
Object.defineProperty(o,"b",{
get(){
return Bvalue;
},
set(newValue){
Bvalue = newValue;
},
enumerable:true,
configurable:true
});
console.log(o.a);
修改属性writable:当writable属性设置为false时,该属性被称为“不可写的”。
var o = {
};//创建一个对象
Object.defineProperty(o,'a',{
value:37,
writable:false,
})
console.log(o.a);
o.a = 25;
console.log(o.a);
Enumerable 属性:定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。
var o = {
};
Object.defineProperty(o,"a",{
value:1,enumerable:true});
Object.defineProperty(o,"b",{
value:2,enumerable:false});
Object.defineProperty(o,"c",{
value:3});
o.d = 4;
Object.defineProperty(o,Symbol.for('e'),{
value:5,
enumerable:true
});
for(var i in o){
console.log(i);
}
console.log(Object.keys(o));
configurable 特性:表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。
var o = {
};
Object.defineProperty(o,"a",{
get(){
return 1},
configurable:false,
});
Object.defineProperty(o,"a",{
configurable:true,
});
Object.defineProperty(o,"a",{
enumerable:true,
});
Object.defineProperty(o,"a",{
set(){
}
});
Object.defineProperty(o,"a",{
get(){
return 1},
configurable:false,
});
Object.defineProperty(o,"a",{
value:12
});
console.log(o.a);
delete o.a;
console.log(o.a);
会在第14行报错。
设置getter()和setter()
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this,'temperature',{
get:function(){
console.log('get!');
return temperature;
},
set:function(value){
temperature = value;
archive.push({
val:temperature});
}
});
this.getArchive = function(){
return archive};
}
var arc = new Archiver();
arc.temperature;
arc.temperature = 11;
arc.temperature = 13;
console.log(arc.getArchive());
参考资料:MDN