Proxy 代理对象

288 阅读2分钟

你可能对 Proxy 稍感疑惑,首先我们举个例子来形象地解释下这个单词。

现代人都有网上购物的习惯。在原来的交易过程中,消费者和卖家一手交钱一手交货。

而网上购物不同。平台代替消费者向卖家买进,消费者把钱给到平台,买家收到信息后打包让快递小哥送货上门。当消费者收到货后,平台再将钱转给卖家,就这样达成了买卖交易。

在这个过程中,平台就扮演 Proxy 代理对象的角色。

本篇文章主要聊以下两点:

  • Proxy 的基本用法

  • Proxy 和 Object.defineProperty 的对比

Proxy 基本用法

换到代码层面,那就是我们想去访问一个对像,不再是直接去访问或修改这个对象,而是通过 Proxy 代替我们去访问或修改某个对象。上代码瞅瞅。

直接访问

//直接访问 objlet obj = {name:"zhangsan"}
obj.name = "lisi" //直接修改
console.log(obj.name//直接访问

代理访问

//代理访问
let obj = {name:"zhangsan"}
let proxy = new Proxy(obj,{  //代理对象
    get(target,property){
        return "lisi"//返回值就是访问的值
    }  //监视访问
    set(target,property,value){
        target[property] = value
    }  //监视设置
})

对于上面的代码,要注意 get() 方法里面的返回值就是代替访问后的值,你不返回那它就是 undefined。对于 set() 方法里面就是代理对属性的直接操作。

而对于 Proxy 的第二个参数,大家可以参考网址。 

对比 Object.defineProperty

Object.defineProperty() 这个方法也可以起到代理对象的作用,但是它只能代理对对象的访问和写入,而对于删除和对对象中方法的调用,Object.defineProperty() 就无计可施了。

这样一对比 Proxy 就显得更加强大了,它能干的事太多了。详见下图。

Proxy 更好的支持对数组对象的监视

我们直接看一个案例。

const list = []
const proxy = new Proxy(list,{
  set(target,property,value){
    console.log("set",property,value)
    target[property] = value
    return value
  }
})
proxy.push("勾勾")

当我们在向数组中添加**“勾勾”**时就会触发 set 的执行。

综上,我们可以看出 Proxy 比 Object.defineProperty 更加强大,并且所操作的范围很广。

同时,我们在监视一个对象的时候,不需要使用这个对象本身去操作,而是使用代理对象去操作,这样在语法上比 Object.defineProperty 更加友好。这也是很多框架越来越喜欢使用 Proxy 的原因。