Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法: Object.defineProperty(obj, prop, descriptor)参数: 参数1: 要定义属性的对象
参数2: 要定义或修改的属性的名称或Symbol
参数3: 要定义或修改的属性描述符
返回值: 返回传递给函数的对象.sdf
配置项:
const object1 = {
name: 999
};
Object.defineProperty(object1, 'property1', {
configurable: true, //该属性的描述符是否能够改变,默认为false
value: 42, //属性名称的值.默认undefined
writable: true, //可读,可写,为true时,value的值才能被改变,默认false
enumerable: true, //是否可枚举,默认为false
// get 属性的getter函数,没有则为undefined,访问该属性时,会调用此函数.
get() { return xxx }
// set 属性的setter函数,没有则为undefined,当属性值被修改时,调用此函数,
该方法接受一个参数(也就是被赋予的新值)
set(newValue) { xxx = newValue }
});
var obj = {};
//方法1:
// var descriptor = Object.create(null); // 没有继承的属性
// // 默认没有 enumerable,没有 configurable,没有 writable
// descriptor.value = 'static';
// Object.defineProperty(obj, 'key', descriptor);
//方法2:
// 显式
// Object.defineProperty(obj, "key", {
// enumerable: false,
// configurable: false,
// writable: false,
// value: "static"
// });
// console.log(obj)
//方法3:
// 循环使用同一对象
function withValue(value) {
return {
enumerable: false,
writable: false,
configurable: false,
value
};
}
// ... 并且 ...
Object.defineProperty(obj, "key", withValue("static"));
Writable属性:
当 writable
属性设置为 false
时,该属性被称为“不可写的”。它不能被重新赋值。
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
value: 37,
writable: false
});
console.log(o.a); // 37
o.a = 25; // "TypeError: Cannot assign to read only property 'a' of object
'#
Enumerable属性:
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 }); // enumerable 默认为 false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
for (var i in o) { console.log(i) } //返回a,d
Configurable属性:
configurable
特性表示对象的属性是否可以被删除,以及除 value
和 writable
特性外的其他特性是否可以被修改。
var o = {};
Object.defineProperty(o, 'a', {
get() { return '999' },
// value: '88', //报错
// enumerable: true, //报错
configurable: false
})
console.log(o.a)
delete o.a //报错:"TypeError: Cannot delete property 'a' of #
添加多个属性和默认值:
var o = {}; o.a = 1; // 等同于: Object.defineProperty(o, "a", { value: 1, writable: true, configurable: true, enumerable: true }); // 另一方面, Object.defineProperty(o, "a", { value : 1 }); // 等同于: Object.defineProperty(o, "a", { value: 1, writable: false, configurable: false, enumerable: false });
自定义Setters和Getters
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
get: function() {
return temperature;
},
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature = 11;
console.log(arc.temperature) // 'get!' 11
arc.temperature = 13;
console.log(arc.temperature) // 'get!' 13
console.log(arc.getArchive()); // [{ val: 11 }, { val: 13 }]
继承属性:
如果访问者的属性是继承的,它的get和set方法会在子对象的属性被访问或修改时被调用.
如果这些方法用一个变量存值,该值会被所有对象共享.
function myClass() {
}
var value;
Object.defineProperty(myClass.prototype, "x", {
get() {
return value;
},
set(x) {
value = x;
}
});
var a = new myClass();
var b = new myClass();
a.x = 1;
console.log(b.x); // 1
这可以通过将值存储在另一个属性中解决.
在get个set方法中,this指向某个被访问和修改属性的对象.
function myClass() {
}
Object.defineProperty(myClass.prototype, "x", {
// 这里this指向myClass
get() {
return this.stored_x;
},
set(x) {
this.stored_x = x;
}
});
var a = new myClass();
var b = new myClass();
a.x = 1;
console.log(b.x); // undefined
不想访问者属性,值属性始终在对象自身上设置,而不是一个原型.
然而,如果一份不可写的属性被继承,它仍可以防止修改对象的属性.
function myClass() {
}
myClass.prototype.x = 1;
Object.defineProperty(myClass.prototype, "y", {
writable: false,
value: 1
});
var a = new myClass();
a.x = 2;
console.log(a.x); // 2
console.log(myClass.prototype.x); // 1
a.y = 2; // 报错: 不能为对象的只读属性赋值
console.log(a.y); // 1
console.log(myClass.prototype.y); // 1
总结于MDN,链接
Object.defineProperty() - JavaScript | MDN