DefineProperty
JavaScript
const handler = {
get: () => {
console.log('get');
return obj['test'];
},
set: value => {
console.log('set', { value });
obj['test'] = value;
},
};
const obj = {
test: {},
test2: {},
};
const proxy = Object.defineProperties(
{ ...obj },
{
test: handler,
}
);
console.log('# proxy.test.a -> get');
proxy.test.a;
console.log('# proxy.test.a = 1 -> get');
proxy.test.a = 1;
console.log("# proxy.test['a'] = 1 -> get");
proxy.test['a'] = 1;
console.log('# proxy.test -> get');
proxy.test;
console.log('# proxy.test = {} -> set');
proxy.test = {};
console.log("# proxy['test'] = {} -> set");
proxy['test'] = {};
// 结论: 添加监听的时候只能一个一个添加监听, 不能监听未定义的对象
// 不能监听 delete
// 直接对 proxy.test 进行赋值, 获取会正常触发
// 对 proxy.test[PROPERTY] 进行赋值, 获取只会触发 get 监听
// 对 test[PROPERTY] 进行操作则不会触发监听
Proxy
JavaScript
const handler = {
get: (target, key, receiver) => {
const result = Reflect.get(target, key, receiver);
console.log('get', { target, key });
return result;
},
set: (target, key, value, receiver) => {
const result = Reflect.set(target, key, value, receiver);
console.log('set', { target, key, value });
return result;
},
deleteProperty: (target, key) => {
const result = Reflect.deleteProperty(target, key);
console.log('deleteProperty', { target, key });
return result;
},
};
const proxy = new Proxy(
{
test: {
a: 12,
},
},
handler
);
proxy.test = 123;
proxy.test
// 结论:
// proxy 只会对对象的属性的第一层添加监听
// 直接对 proxy.test 进行赋值, 删除, 获取会正常触发
// 对 proxy.test[PROPERTY] 进行赋值, 删除, 获取只会触发 get 监听
// 对 test[PROPERTY] 进行操作则不会触发监听
// 千万不要在get方法中读取receiver的属性,因为receiver实质上就是proxy自身,所以receiver.key这句代码就等同于proxy.key,会重新调用get方法导致死循环
Discussion
留言与讨论
想法、补充和不同意见都欢迎。