Object.defineProperty
Object.defineproperty 的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
使用Object.defineProperty之前
number和person之间并无关联
使用Object.defineProperty之后
person和number之间有了关联;修改person.age之后,number发生了变化;修改number之后,person.age变化了
*get:当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
set:当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值*
对象的属性描述符
①对象除了我们最初理解的key,value键值对形式,还有其他的属性描述符,如下:
②writable 对象的某个value能否更改;
③enumerable 能够被列出;
④configurable 能够被删除
对象不只是有value属性描述符
使用普通方法创建对象之后,他的属性描述符writable enumerable configurable默认都是true
let user = {
name: "John"
};
//获取user对象的name属性的描述符
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
alert( JSON.stringify(descriptor, null, 2 ) );
/* 属性描述符:
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
*/
如果使用Object.defineProperty(obj, propertyName, descriptor)创建对象的某一属性,那么上面的三个属性描述符默认是false
obj是对象;propertyName是属性名;descriptor是属性描述符对象
let user = {};
Object.defineProperty(user, "name", {
value: "John"
});
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
alert( JSON.stringify(descriptor, null, 2 ) );
/*
{
"value": "John",
"writable": false,
"enumerable": false,
"configurable": false
}
*/
Object.defineProperties一次定义多个属性
Object.defineProperties(user, {
name: { value: "John", writable: false },
surname: { value: "Smith", writable: false },
// ...
});
对象的另外一种属性:访问器属性 getter setter
①对象属性包括数据属性(常规的)和访问器属性
②访问器属性有getter和setter两个函数组成,可以用来随时改变对象中的属性值;
③当读取对象中某一个属性的时候,触发getter函数
④当修改对象中的某一个属性的时候,触发setter函数
⑤访问器属性对内表现为getter、setter函数,对外仍然表现为某一个数据属性
访问器属性讲解参考
现在我们想添加一个 fullName 属性,该属性值应该为 “John Smith”。当然,我们不想复制粘贴已有的信息,因此我们可以使用访问器来实现:
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
};
alert(user.fullName); // John Smith
通过为 user.fullName 添加一个 setter 来修改属性值
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
},
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
// set fullName 将以给定值执行
user.fullName = "Alice Cooper";
alert(user.name); // Alice
alert(user.surname); // Cooper
访问器描述符
对于访问器属性,没有 value 和 writable,但是有 get 和 set 函数。
所以访问器描述符可能有:
get —— 一个没有参数的函数,在读取属性时工作,
set —— 带有一个参数的函数,当属性被设置时调用,
enumerable —— 与数据属性的相同,
configurable —— 与数据属性的相同。
请注意,一个属性要么是访问器(具有 get/set 方法),要么是数据属性(具有 value),但不能两者都是。
如果我们试图在同一个描述符中同时提供 get 和 value,则会出现错误:
// Error: Invalid property descriptor.
Object.defineProperty({}, 'prop', {
get() {
return 1
},
value: 2
});