- 作者简书首页https://www.jianshu.com/u/d672e5d7dc0d
- 保证每周至少三篇文章
需求: 对一个对象实现监视,即监视对象所有属性的增删改查
概念
Object.defineProperty()
:方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
方法
Object.defineProperty(obj,prop,descriptor);
简单的使用
- 新增属性
let obj = {};
Object.defineProperty(obj,"name",{
value: "kevin",
writable: true, // 赋予写权限
enumerable: true, // 可遍历权限
configurable: true // 可配置的权限
})
console.log(obj); // { name: 'kevin' }
// 1.1 通过defineProperty定义赋值的属性不能改变,
// 必须添加 **writable: true** 才能修改对象的属性
obj.name = "Tom";
console.log(obj); // { name: 'Tom' }
// 1.2 通过defineProperty定义赋值的属性不能遍历
// 必须添加 **enumerable: true** 才能修遍历
for (const key in obj) {
console.log(key,obj[key]); // name Tom
}
// 1.3 通过defineProperty定义赋值的属性不能删除
// 必须添加 **configurable: true** 才能删除
delete obj.name;
console.log(obj); // {}
get/set使用
- 通过属性的get/set来监听属性变化,获取属性自动调用
get方法
,设置属性自动调用set方法
- get/set 和Object.defineProperty中 value、writable 属性不能共存
let obj2 = {}
let oldValue = "kevin"
// get/set 和 value、writable 不能共存
Object.defineProperty(obj2, "name", {
// value: "kevin",
// writable: true,
enumerable: true,
configurable: true,
set(newValue) {
console.log("执行set方法,旧值为", newValue);
if (oldValue !== newValue) {
console.log("执行set方法,新值为", newValue);
oldValue = newValue;
}
},
get() {
console.log("执行get方法,属性为", oldValue);
return oldValue;
}
})
obj2.name = "Tom"; // 执行set方法,旧值为 kevin. 执行set方法,新值为 Tom
console.log(obj2.name); // 执行get方法,属性为 Tom
实现对象属性的检测
// 监视对象类
class ObserverObject {
// 构造器
constructor(obj) {
this.observer(obj)
}
// 监视方法
observer(obj) {
if (obj && typeof obj === "object") {
for (const key in obj) {
this.observerRealize(obj, key, obj[key]);
}
}
}
// 监视实现
observerRealize(obj, key, value) {
// 如果属性的取值是一个对象, 也需要给这个对象的所有属性添加get/set方法
// 例子: value为对象
this.observer(value)
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: () => {
return value;
},
set: (newValue) => {
console.log('数据的变化前', value);
if (newValue !== value) {
// 如果属性的取值是一个对象, 也需要给这个对象的所有属性添加get/set方法
// 例子: newValue为对象
this.observer(newValue);
value = newValue;
console.log('数据的变化后', newValue);
}
}
})
}
}
let obj = {
name: "kevin",
detail: {
age: 18
}
}
new ObserverObject(obj);
obj.name = "Tom"; // 数据的变化前 kevin , 数据的变化后 Tom
obj.detail.age = 20; // 数据的变化前 18 , 数据的变化后 20
obj.name = { a: "aaa" }; // 数据的变化前 Tom , 数据的变化后 { a: [Getter/Setter] }
obj.name.a = "bbb"; // 数据的变化前 aaa , 数据的变化后 bbb
网友评论