资讯专栏INFORMATION COLUMN

ES6中的代理(Proxy)和反射(Reflection)

Markxu / 3011人阅读

摘要:代理和反射的定义调用可常见代替其它目标对象的代理,它虚拟化了目标,所以二者看起来功能一致。代理可拦截引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。

代理和反射的定义

调用 new Proxy() 可常见代替其它目标 (target) 对象的代理,它虚拟化了目标,所以二者看起来功能一致。

代理可拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。

反射 API 以 Reflect 对象的形式出现,对象中方法的默认特性与相同的底层操作一致,而代理可以覆写这种操作,每一个代理陷阱对应一个命名和参数都相同的 Reflect 方法。

应用

基础用法

let target = {};
let p = new Proxy(target, {});

p.a = 37;   // 操作转发到目标

console.log(target.a);    // 37. 操作已经被正确地转发

get、set、has、deleteProperty的使用

get() 方法用于拦截对象的读取属性操作

set() 方法用于拦截设置属性值的操作

has() 方法可以看作是针对 in 操作的钩子

deleteProperty() 方法用于拦截对对象属性的 delete 操作

let target = {
  name: "target",
  color: "blue",
  size: 50,
  skill: "drink"
}
let proxy = new Proxy(target, {
  set: function(trapTarget, key, value, receiver) {
    // 忽略不希望受到影响的已有属性
    if(!trapTarget.hasOwnProperty(key)) {
      if(isNaN(value)) {
        throw new TypeError("属性必须是数字!")
      }
    }
    //添加属性
    return Reflect.set(trapTarget, key, value, receiver)
  },

  get: function(trapTarget, key, receiver) {
    if(!(key in receiver)) {
      throw new TypeError(key + "属性不存在!")
    }

    return Reflect.get(trapTarget, key, receiver)
  },

  has: function(trapTarget, key) {
    if(key === "color") {
      return false
    }else {
      return Reflect.has(trapTarget, key)
    }
  },

  deleteProperty: function(trapTarget, key) {
    if(key === "skill") {
      return false
    }else {
      return Reflect.deleteProperty(trapTarget, key)
    }
  }

});

//添加一个新属性
proxy.count = 1
console.log(target.count) //1
proxy.name = "proxy"
console.log(proxy.name) //proxy
console.log(target.name) //proxy
proxy.anotherName = "proxy" //抛出错误: 属性必须是数字!

console.log(proxy.age) //抛出错误:age属性不存在!

console.log("name" in proxy) //true
console.log("color" in proxy)  //false


console.log("size" in proxy) //true
let result1 = delete proxy.size
console.log("size" in proxy) //false

console.log("skill" in proxy) //true
let result2 = delete proxy.skill
console.log("skill" in proxy) //true
参考

《深入理解ES6》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102804.html

相关文章

  • 深入理解ES6笔记(十一)代理Proxy反射Reflection)API(12)

    摘要:是陷阱函数对应的反射方法,同时也是操作的默认行为。对象外形指的是对象已有的属性与方法的集合,由于该属性验证只须在读取属性时被触发,因此只要使用陷阱函数。无论该属性是对象自身的属性还是其原型的属性。 主要知识点:代理和反射的定义、常用的陷阱函数、可被撤销的代理、将代理对象作为原型使用、将代理作为类的原型showImg(https://segmentfault.com/img/bVbfWr...

    explorer_ddf 评论0 收藏0
  • 《深入理解ES6》笔记——代理Proxy反射Reflection)API(12)

    摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。 反射 Reflect 当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。 showImg(https://segmentfault....

    ZHAO_ 评论0 收藏0
  • 《深入理解ES6》笔记——代理Proxy反射Reflection)API(12)

    摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。 反射 Reflect 当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。 showImg(https://segmentfault....

    shiina 评论0 收藏0
  • ES6Proxy & Reflection API

    摘要:的出现,使用内建对象的继承得以实现。属性不存在抛出异常是取值操作,而就是赋值操作,可以对属性值进行验证。属性必须为数字抛出异常接受两个参数被读取属性的原对象,即代理的目标。这个可以拦截内部方法,通过返回数组的值可以覆写其行为。 Proxy & Reflect extends的出现,使用内建对象的继承得以实现。Proxy可以拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响...

    yearsj 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<