1.Object.definedProperty的实现拦截必须得声明一个额外的变量,例如下面这样
constobj={};let_data="这是一些数据";Object.defineProperty(obj,"data",{get(){console.log("读取data的操作被拦截了");return_data;},});console.log(obj.data);但是如果你这么写,就会报错,栈溢出,因为递归调用了
2.使用proxy,可以定义空对象,里面不写属性值,他不会报栈溢出的原因也是因为没有递归调用,根本原因是因为拦截器返回的不是它本身,而是obj的属性值
constobj={};constp=newProxy(obj,{get(obj,prop){console.log(`${prop}的读取操作被拦截了`);returnobj[prop];},});console.log(p.data);console.log(p.name);
3.如果你这么写,同样会报栈溢出
5.如果想要实现和proxy类似功能,可以这样写
constobj={name:'syt',age:4};consthandler={get(target,prop){console.log(`${prop}的读取操作被拦截了`);returntarget[prop];// target是另一个对象},set(target,prop,value){console.log(`${prop}的设置操作被拦截了`);target[prop]=value;// target是另一个对象returntrue;}};// 手动实现类似Proxy的功能functioncreateProxy(target,handler){constproxy={};Object.keys(target).forEach(key=>{Object.defineProperty(proxy,key,{get(){returnhandler.get(target,key);// 这里不会递归},set(value){handler.set(target,key,value);}});});returnproxy;}constp=createProxy(obj,handler);console.log(p.name)p.age=18
6.但是,这种写法,也是必须的在obj中写上所有的key,才可以拦截到,如果你不写的话就拦截不到
7.如果使用proxy的话,就可以不用定义key,写一个空的对象就可以
当然这两个只是拿get和set来做对比,简单记录下