好奇一研之使用Proxy实现对象深层创建并赋值
2020.12.31 15:13
研这玩意还是突发奇想,在Vue3的Reactive实现上进行想法产生的,前辈们的源码可真的太让我学到了好些,十分感谢
直接上码
var o = {};
const handlerProxy = {
get(target, key) {
let res = Reflect.get(target, key);
if (target.hasOwnProperty(key)) {
if (typeof res === 'object' && res !== null) {
return new Proxy(res, handlerProxy);
} else {
return res;
}
} else {
Reflect.set(target, key, {});
res = Reflect.get(target, key);
return new Proxy(res, handlerProxy);
}
},
set(target, key, val) {
return Reflect.set(target, key, val) && val;
},
};
var p = new Proxy(o, handlerProxy);
大概原理就是在赋值的同时会触发代理的get,从而进行判断处理
如属性(key)存在于当前代理的对象(target)之中 ↓
if (target.hasOwnProperty(key))
则判断一下是否为对象(Array、Object),不为null哦↓
if (typeof res === 'object' && res !== null)
如为对象,再进行一层代理而返回 ↓
return new Proxy(res, handlerProxy);
Vue3的响应式,Reactive,之所以效率比Vue2的Object.defineProperty快,也是因为这个原因,只有Get用到的时候才会进行响应Proxy代理注册,而不用到时则单单的在内存里做个沉默是金的娃子。哈哈,可以将Vue3的响应式称之为懒加载系列了,Vue2则需要在声明的时候直接递归遍历对象的所有属性,将其设置上相应的get/set,两者对比起来,效率显而易见,Vue3 Yes!
如不为对象,那肯定是原始值了,直接无脑返回就好啦。 ↓
return res;
此时,重点来了…如属性(key)不存在于当前代理的对象(target)之中
将不存在的属性进行创建,并赋成对象,也就是++Reflect.set(target, key, {})++
这里为什么要使用Reflect呢,是因为Reflect已经将一些繁琐的操作进行包装了,我们只需要通过它一行代码就可以反射实现本该几行代码才能完成的事情!当然的,Vue3中就是采用的Reflect。
而后呢,再将刚创建好的对象再进行一次代理而返回(这里也就是深层赋值的核心点,如此层不存在,而新建此层,从而返回回去再进行 下一层操作或者赋值操作)↓
res = Reflect.get(target, key);
return new Proxy(res, handlerProxy);
