# 实用-手写响应式
# Object.property
var obj = { name: "Aaron" };
function reactive(target) {
if (typeof target === "object" && target !== null) {
for (let key in target) {
defineReactive(target, key, target[key]);
}
}
}
function defineReactive(target, key, val) {
Object.defineProperty(target, key, {
enumerable: true,
configurable: true,
get: function () {
console.log('get invoked');
return val;
},
set: function (newVal) {
if (newVal != val) {
console.log(`set invoked ${val} => ${newVal}`);
val = newVal; // 这里利用到了闭包,可以直接赋值代替 target[key],后者会导致堆栈溢出
}
},
});
}
reactive(obj);
console.log(obj.name);
obj.name = "Vera";
console.log(obj.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Proxy
var obj = { name: "Aaron" };
function reactive(target) {
return new Proxy(target, {
get: function(obj, key) {
console.log('get invoked')
return obj[key];
},
set: function(obj, key, newVal) {
let val = obj[key];
if (val !== newVal) {
console.log(`set invoked change from ${val} => ${newVal}`)
obj[key] = newVal;
}
}
})
}
let proxyObj = reactive(obj);
console.log(proxyObj.name);
proxyObj.name = "Vera";
console.log(proxyObj.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22