当前位置: 首页 > Web前端 > HTML5

defineProperty和Proxy的区别

时间:2023-04-05 11:00:18 HTML5

在Vue2和3中,defineProperty和Proxy都是用来实现响应式数据绑定的。实现的功能类似,但两者的API有本质区别。从监控数据的角度来看,defineproperty只能监控某个属性,不能监控整个对象。代理不需要设置具体的属性,而是直接监控整个对象。defineproperty监听器需要知道它是哪个对象的哪个属性,代理只需要知道它是哪个对象即可。即省略forin循环,提高效率。监控对原对象的影响因为defineproperty是在原对象上增加或修改属性,增加描述符达到的监控效果,所以原数据肯定会被修改。代理只是原对象的代理,代理会返回一个代理对象,不会修改原对象,不会污染原数据。实现对数组的监听,因为数组长度的特殊性(length的描述符configurable和enumerable都是false,如果尝试修改configurable为True,js会直接报错:VM305:1UncaughtTypeError:Cannotredefineproperty:length)defineproperty无法监听数组的长度变化,Vue只能通过重写数组方法来实现监听效果,仅靠重写数组方法仍然无法解决修改数组下标时的监听问题。它只能使用自定义的$set方法和代理,因为它本身的特点是创建一个新的代理对象,而不是在原始数据上监控属性。在操作代理对象时,所有的操作都会被捕获,包括数组方法和长度操作,不需要重写数组方法和自定义set函数。向上。(代码示例如下)4.defineproperty的监控范围只能监控getsetofvalue的变化。代理可以监控除[[getOwnPropertyNames]]之外的所有JS对象操作。(见以下链接)监测范围更大更全面。点击查看proxy支持监听的对象操作方法(getOwnPropertyNames除外)。Proxy监听数组变化示例:letarray=['1','2']letarrayProxy=newProxy(array,{get(target,key){console.log('(key:',key+")agetoperationoccurred")returntarget[key]},set(target,key,value){console.log('(key:',key+")asetoccurredoperation,value="+value)returntarget[key]=value}})arrayProxy.push('我是push函数推送到数组中的值')//(key:push)发生了get操作//(key:length)发生了get操作//(key:2)发生了set操作,value=我是push函数推送到数组中的value//(key:length)发生了set操作,value=3//从log中可以看出这样的操作因为推送长度已被捕获