js的Proxy代理对象?看完你就会了!

  

  通过捕捉器,我们就可以捕获到 代码中对属性的操作时机,让我们能够先执行我们自定义的业务逻辑代码。因为我们对目标对象的属性操作改为了对代理对象相同的属性操作,所以我们在最后需要通过Reflact执行目标对象的原始操作。优品拍拍

  var consume = 0

  // 目标对象

  var obj = {wallet: 100}

  // 捕获器trap

  var handlers = {

  set(target, key, val) {

  // target 目标对象

  // key 代理对象要修改的属性

  // 记录一笔消费

  consume++

  // 通过Reflact对象触发原始目标对象的属性操作

  // 相当于执行 target[key] = val

  Reflect.set(target, key, val)

  }

  }

  // 代理对象

  var pObj = new Proxy(obj, handlers)

  // 将对目标对象obj的属性wallet操作改为代理对象相同属性wallet的操作you

  pObj.wallet = 97

  pObj.wallet = 94

  pObj.wallet = 91

  pObj.wallet = 88

  pObj.wallet = 85

  console.log(obj.wallet) // 85

  console.log(consume) // 5

  如何取消代理

  假如某一天,你实现了财务自由,不需要再精打细算记录每一笔消费了,你可能就需要取消此前的代理,代码很简单,往下看

  var consume = 0

  var obj = {wallet: 100}

  var handlers = {

  set(target, key, val) {

  consume++

  Reflect.set(target, key, val)

  }

  }

  // 使用Proxy.revocable创建代理

  var tmpObj = Proxy.revocable(obj, handlers)

  var pObj = tmpObj.proxy

  var prevoke = tmpObj.revoke

  // 使用代理对象进行消费记账

  pObj.wallet = 97

  pObj.wallet = 94

  pObj.wallet = 91

  // 某一天,我们实现了一个小目标

  pObj.wallet = 100000000

  // 我们不需要记账了,我们需要取消创建的代理

  prevoke() // 执行prevoke即可,就是这么简单 哦耶~

  pObj.wallet = 99999997 // TypeError 报错啦 (代理取消之后就不能使用了哟!)

  代理在后模式

  前面的示例都是先执行代理捕获器中的业务逻辑,最后再通过Reflect执行目标对象的属性操作,这种捕获代码操作在前,目标对象操作在后的模式称为“代理在先”模式,有在先,当然就有在后模式。

  当然这里的“代理在后”模式并不是先使用Reflect对象触发目标对象属性操作,在执行捕获器中的其他操作代码。而是指代理作为目标对象的一种补充,我们仍然操作的是目标对象,只是当某些操作在目标对象上无法实现时,才使用代理对象。

  等会,当某些操作目标对象无法提供时,js会向目标对象的原型prototype上进行查找,所以“代理在后”模式是对目标对象的原型进行代理!

  var handlers = {

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以。JavaScript中的Proxy对象是ECMAScript 6中引入的一个新特性,它允许我们在访问一个对象之前,对这个对象进行拦截和修改。换句话说,Proxy对象是一个用于定义基本操作的对象,这些基本操作包括读取、写入、函数调用等。我们可以使用Proxy对象来创建一个拦截器,来捕获并处理操作,比如对属性进行访问、设置、删除等。 Proxy对象有两个参数:target和handler。target是要拦截的目标对象,handler是一个对象,用于定义拦截目标对象的各种操作。handler中定义了各种拦截器,用于拦截目标对象的不同操作,包括get、set、apply等。 以下是一个示例代码,说明如何使用Proxy对象: ``` let obj = { name: "John", age: 30 }; let handler = { get: function(target, prop) { if (prop === "age") { return target[prop] + " years old"; } else { return target[prop]; } }, set: function(target, prop, value) { if (prop === "age" && typeof value !== "number") { throw new TypeError("Age must be a number"); } else { target[prop] = value; } } }; let proxy = new Proxy(obj, handler); console.log(proxy.name); // Output: John console.log(proxy.age); // Output: 30 years old proxy.age = 35; console.log(proxy.age); // Output: 35 years old proxy.age = "35"; // Throws a TypeError: Age must be a number ``` 在这个例子中,我们定义了一个对象obj,然后创建了一个Proxy对象proxy,对obj对象进行拦截操作。handler对象中定义了get和set拦截器,用于在读取和设置obj对象的属性时进行拦截和处理。 当我们使用proxy.name来获取name属性时,get拦截器被触发,它返回obj对象中的name属性的值。而当我们使用proxy.age来获取age属性时,get拦截器也被触发,但是它返回的是一个字符串,即obj对象中age属性的值加上" years old"。 当我们使用proxy.age = 35来设置age属性时,set拦截器被触发,它将35赋值给obj对象的age属性。而当我们使用proxy.age = "35"来设置age属性时,set拦截器也被触发,但是它抛出一个类型错误,因为age属性必须是一个数字。 总的来说,Proxy对象为JavaScript中的对象操作提供了更加灵活的拦截和处理方式,它可以用于实现一些高级功能,比如数据绑定、权限控制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值