视频链接
⚠️视频里使用proxy的代码不能用!!!
(1)简单使用
javascript">const obj = {a: 1,b: 2,c: {a: 1,b: 2,},
};
let v = obj.a;
Object.defineProperty(obj, "a", {get() {console.log("读取", 'a');},set(val) {if (v !== val) {console.log("更改", "a");v = val;}}})
(2)递归调用
javascript">let _vue = {};
function _isObject(v) {return typeof v === 'object' && v != null;
}
function observe(obj) {let _vfor (const k in obj) {let v = obj[k];if (_isObject(v)) {observe(v);} else {Object.defineProperty(obj, k, {get() {console.log("读取", k);return },set(val) {if (v !== val) {console.log("更改", k);v = val;}}})}}
}
const obj = {a: 1,b: 2,c: {c1: 1,c2: 2,},
};
observe(obj);obj.a;
obj.a = 3;
obj.c.c1;
obj.c.c2 = 4;
2、Proxy
javascript">let target = {a: 1,b: 2,c: {c1: 1,c2: 2}
}
function _isObject(val) {return typeof val === 'object' && val !== null;
}function observer(target) {let proxy = new Proxy(target, {get(trapTarget, prop, receiver) {/*** 设置对象c下面的属性c1 时,分为2步,首先读取c,然后再设置c1,* 所以我们在get捕获器中判断如果读取的是对象,则返回代理。 */if (_isObject(trapTarget[prop])) {return observer(trapTarget[prop])}else{return trapTarget[prop];}},set(trapTarget, prop, val, receiver) {// console.log(trapTarget, prop, val, receiver);trapTarget[prop] = valreturn true;}});return proxy;
}
let proxy = observer(target);
proxy.c.c1 = 11;//
console.log(proxy.c.c1);
proxy.c.c2 = 12;//
console.log(proxy.c.c2);
console.log(target);
设置对象c下面的属性c1 时,分为2步,首先读取c,然后再设置c1,所以我们在get捕获器中判断如果读取的是对象,则返回代理对象。