前言:上一节主要学习了【选项合并】,了解了各个选项在初始化阶段的合并策略。本节课,我们来学习【数据代理】】这个知识点。1.数据代理的定义数据代理也称为数据劫持。核心功能有两个:(1)在访问对象的属性时,可以进行其他操作(2)在修改对象的属性时,可以修改返回的结果。说白了就是会自动触发一些函数(方法)。这个函数(方法)处理我们的业务逻辑需求。2.数据代理的类型这里有两种数据代理的方法:(1)Object.defineProperty()在一个对象上定义一个新的属性,或者修改一个已有的属性,并返回这个对象。该方法有三个参数,即:第一个为原始对象,即要操作的对象;二是对象的一个??属性,即要操作的属性;第三个也是一个对象,那些会自动触发的方法是看这里的例子:varobj={name:'Therearefish',age:2};Object.defineProperty(obj,'name',{get(){console.log('访问obj时会自动调用');console.log(obj.age);},set(v){console.log('obj属性修改时会自动调用');obj.age=5;}})obj.name;//获取obj对象的name属性,自动调用get(),输出:会被调用automaticallywhenaccessingobj,2obj.name='year';//修改obj对象的name属性,自动调用set(),输出:当修改obj属性时会自动调用,其他操作已经执行到changetheageto5obj.name;//再次访问obj对象的name属性,自动调用get(),输出:访问obj时会自动调用,5但是这个数据代理的方法有局限性。处理一级对象时没有问题。在处理多层嵌套对象和数组时会出现一些问题。让我们来看看如何处理数组。第一个参数是数组本身,第二个参数是数组的下标,第三个参数还是一样,是包含set()和get()方法的对象。还是看代码:vararr=['Year','Yuyu','Kaka'];for(iinarr){Object.defineProperty(arr,i,{get(){console.log('调用arr时会自动调用access');},set(){console.log('它arr被修改时会自动调用');}});}arr[1]='Loulou';//被修改时可以调用set(),输出:console.log(arr)会是calledautomaticallywhenarrismodified;//访问时可以调用get(),输出:访问arr时会自动调用。这是对原数组的修改,结果是没有问题,但是如果加上arr[3]='loulou'这样的数组就不行了。所以为了解决这种情况,需要使用下面的数据代理方式。(2)Proxy()的数据代理方法其实还是比较容易理解的。就是参照原对象创建一个新的代理对象,我们的操作都是在这个新对象上完成的。它有两个参数,第一个是原始对象,第二个是包含get()和set()的对象,它的返回值是新创建的代理对象。而且它不仅可以处理对象,还可以处理数组和多层对象嵌套。看一个例子:vararr=['year','youyu','kaka'];letobj=newProxy(arr,{get:function(target,key,receiver){console.log("get将在"+key时自动调用);returnReflect.get(target,key,receiver);},set:function(target,key,receiver){console.log('修改时自动调用');returnReflect.set(target,key,receiver);}})obj[2]='loulou';//修改原始数据,调用set(),result:console.log(obj[2])修改时自动调用;//访问数据,调用get(),result:获取时自动调用2obj[5]='Watermelon'//添加新数据,调用set(),结果:修改时自动调用3.数据代理的应用场景一:Vue中的数据响应系统使用了Object.defineProperty()。这个应用场景后面会单独分析,今天就不说了。场景二:Vue在渲染模板时使用了基于Proxy()的新封装方式。initProxy()initProxy()本质上是对Vue实例化对象的一层代理,用于一些数据的过滤和非法拦截。比如过滤$,_开头的Vue内部变量,js的关键字,使用未定义变量的模板等等。4.两种数据代理的优劣Object.defineProperty和Proxy都可以实现数据代理。前者兼容性较好,但不能监控数组或嵌套对象。后者基本可以解决所有问题,但是对于兼容性要求高。后记:送人玫瑰,手留余香!如果您觉得文章对您有帮助,请给个大大的赞,也可以分享出去让更多的人知道!你也是web前端学习者,可以加VX:qingyulan52最后祝你学业进步,早日成为技术高手!!!
