Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法 :Object.defineProperty(obj, prop, descriptor)
参数:
obj: 需要定义的对象;
prop:需要定义或修改的对象的属性的名称
descriptor:将被定义或修改的属性描述符
属性描述符:
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
数据描述符:
configurable: 默认为false 当configurable 为true时该属性描述符才能被改变 ;
enumerable: 可枚举属性 默认为false;
value: 该属性对应的值 默认为undefined
writable: 当该属性为true时 value才能被赋值运算符修改默认为false
存取描述符:
get:
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined
。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this
对象(由于继承关系,这里的this
并不一定是定义该属性的对象)。
set:
一个给属性提供setter的方法,如果没有setter则为undefined,当属性值发生修改是触发该属性方法,该方法接收唯一参数即该属性新的参数值
var person = {};
Object.defineProperty(person, "name", {
writable: true,
value: "zhangsan"
})
console.log(person.name);// zhangsan
person.name = "lisi";
console.log(person.name); //lisi
把configurable 设置为false,则表示不能从对象中删除属性。如果对这个属性调用delete则在非严格模式下什么也不会发生如果在严格模式下则会导致错误。如果一旦把属性配置为不可复制的,就不能再把它变回可配置了。此时在调用object.defineProperty()修改除了writable之外的特性,都会导致错误。
var person = {};
Object.defineProperty(person, "name", {
configurable: false,
value: "zhangsan"
});
//抛出错误
Object.defineProperty(person, "name", {
configurable: true,
value: "lisi"
});
存取描述符之访问器属性:他们包含一对getter和setter函数在读取访问器属性时会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并写入新值,这个函数负责决定如何处理数据。访问器属性有如下四个特性。
【Confiurable】 【Enumerable】【Get】 【Set】
var book = {
_year: 2019,
edition: 1
};
Object.defineProperty(book, "year", {
get: function() {
return this._year;
},
set: function(newVul) {
if(newVal > 2019) {
this._year = newVal;
this.edition += newVul - 2019
}
}
});
this._year = 2020;
console.log(book.edition);
定义多个属性: 由于对象定义多个属性的可能ECMAScript 5 定义了Object.defineproperties()方法这个方法接收两个参数 一需要定义的对象 二要修改的属性和对应的属性描述符
var book = {};
Object.defineProperties(book, {
_year: {
writable: true,
value: 2019
},
edition: {
writable: true,
value: 1
},
year: {
get: function() {
return this._year;
},
set: function(newVal) {
this._year = newVal;
this.edition += this._year - 2019
}
}
});
读取属性的特性 : Object.getOwnPropertyDescriptor()方法
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor.value);// 2019
console.log(descriptor.configurable)// false