02-将对象所有属性变为可侦测
作者:互联网
02-将对象所有属性变为可侦测
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 通过定义1个类 Observer,使用循环递归的方式 将对象的所有属性变成可侦测属性
class Observer {
constructor(value) {
this.value = value;
if (Array.isArray(value)) {
// value是数组的时候,用数组的侦听方式
} else {
// 当对象的时候调用walk实现侦测属性
this.walk(value);
}
}
walk(obj) {
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i])
}
}
}
function defineReactive(obj, key, val) {
// 当只传入2个值的时候,可以直接获取到第三个参数value值
if (arguments.length == 2) {
val = obj[key]
};
// 如果属性的值value也是对象,那么也需要将其变为可侦测
if (typeof val === 'object') {
new Observer(val);
};
// Object.defineProperty 定义属性
Object.defineProperty(obj, key, {
enumerable: true, // 定义此属性出现在for-in循里面,以及Object.keys() 的遍历中
configurable: true, // 定义此属性可以配置和删除
// 取数据的描述符
get() {
console.log(`读取属性: ${key}`);
return val // 获取
},
// 存数据的描述符
set(newValue) {
if (val === newValue) {
return // 相同不用做任何操作
} else {
console.log(`存储属性: ${key}`);
console.log('存入的数据:' + newValue);
val = newValue;// 值改变了
}
}
});
}
let user = {
username: '江哥',
type: '帅',
friend: {
username: '老王'
}
};
new Observer(user)
</script>
</body>
</html>
标签:02,obj,val,keys,value,key,侦测,属性 来源: https://blog.csdn.net/wuj1935/article/details/116207471