有两种类型的数据描述符
第一种是数据属性描述符(DataDescriptor),即上篇博客提到的 (这里应该有个超链接) 四个属性
第二种是访问器属性描述符(AccessorDescriptor),是用于获取和设置值的函数
数据属性描述符:
- configurable
- enumerable
- writable
- value
访问器属性描述符:
- configurable
- enumerable
- set
- get
数据属性描述符对象上不能有get,set属性,访问器属性描述符对象上不能有value,writable属性
一个属性要么是访问器,要么是数据属性,不能两者都是不然会报错
Object.defineProperty({}, 'prop', {
get(){
return 1;
},
value: 2
})
// Error property descriptors must not specify a value or be writable when a getter or setter has been specified
getter 和 setter
let obj = {
get propName() {
console.log('get', 1);
return 1;
// 当读取 obj.propName 时,getter 起作用
},
set propName(value) {
console.log('set', value)
// 当执行 obj.propName = value 操作时,setter 起作用
}
};
// obj.propName; // get 1
// obj.propName=2; // set 2
/* 下面这种写法也可 */
let obj = {}
Object.defineProperty(obj, 'propName', {
enumerable:true,
configurable: true,
get(){},
set(){}
})
// ps.如果只有一个getter赋值时会报错 (严格模式)
有了get/set之后已经没有value不是一般数据属性了,如果get返回定值则无法改变
用getter和setter可以实现类似vue计算属性的效果
let user = {
name: "xiao",
surname: "hong"
};
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
console.log(user.fullName); // xiao hong
user.fullName = "xiao li";
// user:{name: "xiao", surname: "li"}
vue的数据响应式原理就是用get和set了