使用Object.defineProperty
这个api,完成当给一个对象重复赋同一个值
的时候,抛出value is same
异常
data对象如下:
const data = {
name: 'panda',
age: 20,
info: {
major: "CS"
}
}
测试代码如下:
// 自己实现observer函数
observer(data);
console.log(data.name); // 输出panda
data.name = "cat"; // 成功赋值为"cat"
data.name = "cat"; // 抛出"value is same"错误
- 参考资料准备(用于学习defineProperty的使用)
-
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
-
https://www.jianshu.com/p/8fe1382ba135
- 思路及实现
- 写函数observer框架,以name属性为例
const observer = (data) => {
let temp = data.name
Object.defineProperty(data, item, {
get: function () {
return temp;
},
set: function (val) {
if (val === temp) {
throw new Error('value is same');
}
temp = val;
}
})
}
- 上一步测试无误,开始加入for循环(一定注意这一步骤中的temp赋值,是将属性的值赋值给temp)
const observer = (data) => {
for (let item in data) {
let temp = data[item] // 注意此处的赋值,是将data[item](即键值对中的值)赋值给temp
Object.defineProperty(data, item, {
get: function () {
return temp;
},
set: function (val) {
if (val === temp) {
throw new Error('value is same');
}
temp = val;
}
})
}
}
- 对代码进行测试,发现对象中嵌套的对象无法实现功能,经过分析,可以在函数的开始进行一次判断,如果遍历到对象中的某属性类型为对象时,那么再次运行observer函数,直到不是对象为止
const observer = (data) => {
for (let item in data) {
let temp = data[item]
if (typeof temp === 'object') {
observer(temp)
}
Object.defineProperty(data, item, {
get: function () {
return temp;
},
set: function (val) {
if (val === temp) {
throw new Error('value is same');
}
temp = val;
}
})
}
}
- 附上完整源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const data = {
name: 'panda',
age: 20,
info: {
major: "CS",
a: {
b: '123'
}
}
}
const observer = (data) => {
for (let item in data) {
let temp = data[item]
if (typeof temp === 'object') {
observer(temp)
}
Object.defineProperty(data, item, {
get: function () {
return temp;
},
set: function (val) {
if (val === temp) {
throw new Error('value is same');
}
temp = val;
}
})
}
}
observer(data);
// console.log(data.name);
// data.name = "cat";
// console.log(data.name);
// data.name = "cat";
console.log(data.info.a.b);
data.info.a.b = '234'
console.log(data.info.a.b);
data.info.a.b = '234'
</script>
</body>
</html>