胜负已分: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的主要内容,如果未能解决你的问题,请参考以下文章

java游戏开发杂谈 - 有限状态机

WordPress已分页

UIScrollView 具有“惯性”但已分页。

Reverse Proxy Vs Forward Proxy

Forward Proxy vs Reverse Proxy

Docker宣布拥抱k8s,k8s将一统天下?