Proxy(代理)和Reflect(反射)

43 篇文章 3 订阅

23. Proxy(代理)和Reflect(反射)

1. Proxy:

Proxy 是一个代理器,它可以拦截对目标对象的各种操作,包括读取属性、设置属性、函数调用等等。通过使用 Proxy,我们可以在这些操作前后注入自定义逻辑,对这些操作进行拦截、修改、记录等等。这使得我们可以更好地控制对象的行为,实现一些高级的功能。

// Proxy  get()捕获器和set()捕获器使用
let obj = {
  name: "Jack",
  age: 20
}

let objProxy = new Proxy(obj, {
  get(target, property) {
    console.log("获取obj的" + property + "属性");
    return target[property]
  },

  set(target, property, newValue) {
    console.log("设置obj的" + property + "属性值为" + newValue);
    target[property] = newValue
  }
})

console.log(objProxy.name);//获取obj的name属性   Jack
objProxy.age = 30;//设置obj的age属性值为30
console.log(obj.age);//30
2. Reflect:

Reflect 则是一个反射器,它提供了一组可以直接对对象进行操作的方法,这些方法和对象的操作相对应,比如 Reflect.get() 对应对象属性的读取操作,Reflect.set() 对应对象属性的设置操作,Reflect.apply() 对应函数的调用操作等等。通过使用 Reflect,我们可以更加灵活地控制对象的行为,并且可以在这些操作前后注入自定义逻辑。通常ProxyReflect一起使用:

// Proxy与Reflect共同使用
let obj = {
  name: "Jack",
  age: 20
}

let objProxy = new Proxy(obj, {
  get(target, property) {
    console.log("获取obj的" + property + "属性");
    return Reflect.get(target, property)
  },

  set(target, property, newValue) {
    console.log("设置obj的" + property + "属性值为" + newValue);
    Reflect.set(target, property, newValue)
  }
})

console.log(objProxy.name);//获取obj的name属性   Jack
objProxy.age = 30;//设置obj的age属性值为30
console.log(obj.age);//30
3. 代理捕获器和反射方法

代理可以捕获13种不同的基本操作,这些操作有各自对应的反射API方法和参数。

// 13种代理方法
let obj = {
  name: "Jack",
  age: 20
}
// obj = function() {}  //apply/constructor使用函数
let objProxy = new Proxy(obj, {
  // 1. get(目标对象, 属性名, 代理对象)
  // get()捕获器会在获取属性值的操作中被调用。对应的反射API是Reflect.get()
  get(target, property, receiver) {
    console.log("获取属性"+property);
    return Reflect.get(...arguments)
  },

  // 2. set(目标对象, 属性名, 要设置的值, 代理对象)
  // set()捕获器会在设置属性值的操作中被调用。对应的反射API是Reflect.set()
  set(target, property, newValue, receiver) {
    console.log("设置属性值");
    return Reflect.set(...arguments)
  },

  // 3. has(目标对象, 属性名)
  // has()捕获器会在in操作符中被调用。对应的反射API是Reflect.has()
  has(target, property) {
    console.log("in操作符");
    return Reflect.has(...arguments)
  },

  // 4. apply(目标函数, 调用函数时的this, 调用函数时的参数数组)
  // apply()捕获器会在调用函数时被调用。对应的反射API是Reflect.apply()
  apply(targetFn, thisArg, ...args) {
    console.log("函数被调用");
    return Reflect.apply(...arguments)
  },

  // 5. construct(目标构造函数, 构造函数的参数数组, 最初被调用的构造函数)
  // construct()捕获器会在new操作符中被调用。对应的反射API是Reflect.construct()
  construct(target, args, newTarget) {
    console.log("new操作符");
    return Reflect.construct(...arguments)
  },

  // 6. defineProperty(目标对象, 属性名, 属性描述符)
  // defineProperty()捕获器会在Object.defineProperty()中被调用。对应的反射API是Reflect.defineProperty()
  defineProperty(target, property, discriptor) {
    console.log("调用Object.defineProperty() " + property);
    return Reflect.defineProperty(...arguments)
  },

  // 7. getOwnPropertyDescriptor(目标对象, 属性名)
  // getOwnPropertyDescriptor()捕获器会在Object.getOwnPropertyDescriptor()中被调用。对应的反射API是Reflect.getOwnPropertyDescriptor()
  getOwnPropertyDescriptor(target, property) {
    console.log("调用Object.getOwnPropertyDescriptor() " + property);
    return Reflect.getOwnPropertyDescriptor(...arguments)
  },

  // 8. deleteProperty(目标对象, 属性名)
  // deleteProperty()捕获器会在delete中被调用。对应的反射API是Reflect.deleteProperty()
  deleteProperty(target, property) {
    console.log("删除 " + property + " 属性");
    return Reflect.deleteProperty(...arguments)
  },

  // 9. ownKeys(目标对象)
  // ownKeys()捕获器会在Object.keys()及类似方法中被调用。对应的反射API是Reflect.ownKeys()
  ownKeys(target) {
    console.log("拦截获取对象自身属性的操作");
    return Reflect.ownKeys(...arguments)
  },

  // 10. getPrototypeOf(目标对象)
  // getPrototypeOf()捕获器会在Object.getPrototypeOf()中被调用。对应的反射API是Reflect.getPrototypeOf()
  getPrototypeOf(target) {
    console.log("拦截获取对象原型的操作");
    return Reflect.getPrototypeOf(...arguments)
  },

  // 11. setPrototypeOf(目标对象, 新的原型对象)
  // setPrototypeOf()捕获器会在Object.setPrototypeOf()中被调用。对应的反射API是Reflect.setPrototypeOf()
  setPrototypeOf(target, newProto) {
    console.log("拦截设置对象原型的操作");
    return Reflect.setPrototypeOf(...arguments)
  },

  // 12. isExtensible(目标对象)
  // isExtensible()捕获器会在Object.isExtensible()中被调用。对应的反射API是Reflect.isExtensible()
  isExtensible(target) {
    console.log("拦截判断对象是否可扩展的操作");
    return Reflect.isExtensible(...arguments)
  },

  // 13. preventExtensions(目标对象)
  // preventExtensions()捕获器会在Object.preventExtensions()中被调用。对应的反射API是Reflect.preventExtensions()
  preventExtensions(target) {
    console.log("拦截禁止对象扩展的操作");
    return Reflect.preventExtensions(...arguments)
  },

})

objProxy.name;//1. 获取属性name
objProxy.age = 30;//2. 设置属性值
"name" in objProxy;//3. in操作符
objProxy.apply({});//4. 函数被调用 注:targetFn应为函数
new objProxy;//5. new操作符
Object.defineProperty(objProxy, 'nickName', { value: "Jarry" });//6. 调用Object.defineProperty() nickName
console.log(obj);//{name: 'Jack', age: 30, nickName: 'Jarry'}
Object.getOwnPropertyDescriptor(objProxy, "nickName");//7. 调用Object.getOwnPropertyDescriptor() nickName
delete objProxy.nickName;//8. 删除 nickName 属性
Object.keys(objProxy);//9. 拦截获取对象自身属性的操作
objProxy.__proto__;// 10. 拦截获取对象原型的操作
Object.getPrototypeOf(objProxy);//10. 拦截获取对象原型的操作
Object.setPrototypeOf(objProxy, null);//11. 拦截设置对象原型的操作
Object.isExtensible(objProxy);//12. 拦截判断对象是否可扩展的操作
Object.preventExtensions(objProxy);//13. 拦截禁止对象扩展的操作
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端每日三省

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值