Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
1.Object.defineProperty()语法
Object.defineProperty(obj, prop, descriptor)
//obj:要定义属性的对象
//prop:要定义或修改的属性的名称
//descriptor:要定义或修改的属性描述符
2.属性描述符
通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符和存取描述符:
数据描述符
数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。
value:属性的名称对应的值,默认undefined
wirtable:value是否可更改,默认false
Object.defineProperty(person,'name',{
value:'jack',
writable:false//此时不能修改
})
Object.defineProperty(person,'name',{
value:'jack',
writable:true//此时可以修改
})
存取描述符
存取描述符是由 getter 函数和 setter 函数所描述的属性。
get:属性的 getter 函数,如果没有 getter,则为
undefined,
该函数的返回值会被用作属性的值。set:属性的 setter 函数,如果没有 setter,则为
undefined,
该方法接受一个参数,并将该参数的新值分配给该属性。
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; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
数据描述符和存取描述符都有的属性
configurable:属性是否可被删除,以及是否可被重新配置属性,默认为false
enumerable:属性是否会出现在for in 或者 Object.keys()的遍历中,默认为false
let person = {}
Object.defineProperty(person, 'name', {
value: 'jack',
configurable:false//此时不可删除不可重新配置属性
})
let person = {}
Object.defineProperty(person, 'name', {
value: 'jack',
configurable:false//此时可以删除可以重新配置属性
})
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; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true