代理——Proxy
在ES6中,新增了一个类Proxy,Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
- 如果希望监听一个对象的相关操作,那么可以先创建一个代理对象。
- 之后对该对象的所有操作,都通过代理对象来完成。
Proxy的基本使用
语法
const p = new Proxy(target, handler)
target:要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。 handler:一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。 如果我们想要侦听某些具体的操作,那么就可以在handler中添加对应的捕捉器(Trap)
Proxy的get和set的捕获
set的四个参数
target:目标对象property:将被设置的keyvalue:新值receiver: 调用的代理对象get的三个参数
target:目标对象property:将被设置的keyreceiver: 调用的代理对象
实例:
const obj = {name: "abc",age: 18,};const objProxy = new Proxy(obj, {get(target, property, receiver) {console.log("get捕获", property);return target[property];},set(target, property, value, receiver) {console.log("set捕获", property);target[property] = value;},has(target, p) {console.log("has捕获", p);return p in target;},deleteProperty(target, p) {console.log("deleteProperty捕获", p);delete target[p];},});console.log(objProxy.name);objProxy.age = 38;console.log(objProxy);console.log("height" in objProxy);delete objProxy["age"];console.log(objProxy);
Proxy的所有捕获器
in 操作符的捕捉器。
属性读取操作的捕捉器。
属性设置操作的捕捉器。
delete 操作符的捕捉器。
Object.getPrototypeOf 方法的捕捉器。
Object.setPrototypeOf 方法的捕捉器。
Object.isExtensible 方法的捕捉器。
Object.preventExtensions 方法的捕捉器。
Object.getOwnPropertyDescriptor 方法的捕捉器。
Object.defineProperty 方法的捕捉器。
Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
函数调用操作的捕捉器。
new 操作符的捕捉器。
Receiver的作用
如果源对象(obj)有setter、getter的访问器属性,那么可以通过receiver来改变里面的this;
反射——Reflect
Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与Proxy的方法相同。
Reflect不是一个函数对象,因此它是不可构造的。
Reflect的所有静态方法
所有静态方法与Proxy的所有捕获器相对应。
对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和 Function.prototype.apply() 功能类似。
对构造函数进行 new操作,相当于执行 new target(…args)。
和 Object.defineProperty() 类似。如果设置成功就会返回 true
作为函数的delete操作符,相当于执行 delete target[name]。
获取对象身上某个属性的值,类似于 target[name]。
类似于 Object.getOwnPropertyDescriptor()。如果对象中存在该属性,则返回对应的属性描述符, 否则返回 undefined.
判断一个对象是否存在某个属性,和 in运算符 的功能完全相同。
返回一个包含所有自身属性(不包含继承属性)的数组。(类似于 Object.keys(), 但不会受enumerable影响).
类似于 Object.preventExtensions()。返回一个Boolean。
将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true。
设置对象原型的函数. 返回一个 Boolean, 如果更新成功,则返回true。
:::info
Reflect主要提供了很多操作JavaScript对象的方法,有点像Object中操作对象的方法;
比如Reflect.getPrototypeOf(target)类似于 Object.getPrototypeOf();
比如Reflect.defineProperty(target, propertyKey, attributes)类似于Object.defineProperty() ;
尽管二者之间存在 某些细微上的差别 .
:::
实例:
const obj = {name: "abc",age: 18,};const objProxy = new Proxy(obj, {get(target, property, receiver) {console.log("get捕获", property);return Reflect.get(target, property, receiver);},set(target, property, value, receiver) {console.log("set捕获", property);Reflect.set(target, property, value, receiver)},has(target, p) {console.log("has捕获", p);return Reflect.has(target, p)},deleteProperty(target, p) {console.log("deleteProperty捕获", p);Reflect.deleteProperty(target, p)},});console.log(objProxy.name);objProxy.age = 38;console.log(objProxy);console.log("height" in objProxy);delete objProxy["age"];console.log(objProxy);

