胜负已分:Proxy VS Object.defineProperty
Posted 前端呆头鹅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了胜负已分:Proxy VS Object.defineProperty相关的知识,希望对你有一定的参考价值。
Object.defineProperty可以监听属性读写。Proxy是为对象设置访问代理器。
两者都可以用来设置监听,在vue2.0中使用Object.defineProperty进行数据监听,而在vue3.0中改用Proxy,两者有什么区别,又是什么原因促使vue作出如此变更呢?
一 Proxy使用
Proxy是一个类,通过new返回实例的方式来调用。
创建实例时它的构造函数接受两个参数,目标对象和监控对象,目标对象是要进行监控的对象,监控对象是用来配置监控行为的对象,可以设置get,set等属性。
1.1 get:访问操作
当访问proxy实例时,会访问监控对象的get,并传入两个参数,目标对象和访问的属性名。
const person =
name: 'kk',
age: 23
const personProxy = new Proxy(person,
get(target, property)
console.log(target, property) // name: 'kk', age: 23 name
return 100
,
set()
)
console.log(personProxy.name) // 100
这里可以通过get对属性设置默认值。
const personProxy = new Proxy(person,
get(target, property)
return property in target? target[property]: 'default'
,
set()
)
console.log(personProxy.name) // kk
console.log(personProxy.a) // default
如上,在通过get获取值时根据目标对象和访问属性,可以取到实际值,经过运算后将处理后的值return抛出,return的值就是调用实例中取到的值。
1.2 set:赋值操作
当写入proxy实例时,会访问监控对象中配置的set,并传入三个参数,为目标对象和访问的属性名,和写入值。
const personProxy = new Proxy(person,
...
set(target, property,value)
console.log(target, property,value) // name: 'kk', age: 23 name 1
)
personProxy.name = 1
可以在set中设置数据校验。
const personProxy = new Proxy(person,
...
set(target, property, value)
if(property === 'age')
if(!Number.isInteger(value))
throw Error(value + 'is error')
else
target[property] = value
)
二 Proxy优势
2.1 监控更加全面
除了get, set,proxy还有很多其他方法监控其他操作,如delete监控。
const personProxy = new Proxy(person,
...
deleteProperty(target, property)
console.log(target, property)
)
delete personProxy.age // name: 'kk', age: 23 age
2.2 支持数组监视
Object.defineProperty无法对数组进行监视,vue2.0通过重写数组操作方法的方式进行监视。
而proxy可以直接监视数组。
如下,对一个数组设置代理后,对代理运行的push、pop等方法都会转化为set和delete操作,反应在监控对象上。
const person = []
const listProxy = new Proxy(person,
set(target, property, value)
console.log('set', target, property, value)
target[property] = value
return true // 设置成功
,
deleteProperty(target, property)
console.log('del', target, property)
return true
)
listProxy.push(100)
//set [] 0 100
//set [ 100 ] length 1
listProxy.push(200)
//set [ 100 ] 1 200
//set [ 100, 200 ] length 2
listProxy.pop()
//del [ 100, 200 ] 1
//set [ 100, 200 ] length 1
2.3 非侵入式监视
proxy是非侵入的模式监视内部读写。不需要单独对属性设置。
指的一提的是,proxy仍然未实现深度监听,需要通过递归代理的方式监听。
以上是关于胜负已分:Proxy VS Object.defineProperty的主要内容,如果未能解决你的问题,请参考以下文章
Reverse Proxy Vs Forward Proxy