Proxy(代理)和Reflect(反射)

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

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. 拦截禁止对象扩展的操作
相关文章
|
6月前
|
Java
反射&代理
反射&代理
58 0
|
4月前
|
设计模式 JavaScript 前端开发
精读JavaScript中的代理(Proxy)与反射(Reflect)
精读JavaScript中的代理(Proxy)与反射(Reflect)
37 0
|
设计模式 Java
反射和代理
反射和代理
71 0
es6 代理(Reflect)和反射(Proxy)的学习总结
es6 代理(Reflect)和反射(Proxy)的学习总结
|
存储 设计模式 Java
Proxy动态代理机制详解
代理模式给某一个(目标)对象提供一个代理对象,并由代理对象持有目标对象的引用,所谓代理,就是一个对象代表另一个对象执行相应的动作程序。
99 0
Proxy动态代理机制详解
|
存储 JavaScript 前端开发
Proxy-Reflect
JS查漏补缺系列是我在学习JS高级语法时做的笔记,通过实践费曼学习法进一步加深自己对其的理解,也希望别人能通过我的笔记能学习到相关的知识点。这一次我们来了解Proxy-Reflect
121 0
|
监控
代理与反射(二)
代理与反射(二)
95 0
代理与反射(一)
代理与反射(一)
95 0
|
Java
JDK Proxy动态代理解析
JDK Proxy动态代理解析
149 0