JavaScript 中的 Proxy 与 Reflect 教程
目录
get 和 set 捕获器详解
为什么要用 Reflect?
使用语法间接调用内部方法
使用 Reflect 直接调用内部方法
对比总结:
Reflect API 及其与 Proxy 的配合
Proxy 的典型应用场景
Proxy 是 ES6 引入的一种元编程特性。它允许创建一个代理对象来包装目标对象,并拦截对目标对象的各种操作(如属性读取、写入、枚举、函数调用等),从而可以自定义这些操作的行为。语法上,new Proxy(target, handler)
接受两个参数:第一个是要代理的目标对象,第二个是包含各种“捕获器”(traps)的处理器对象。例如,get
捕获器可以拦截属性读取操作,set
捕获器拦截属性写入操作等等。如果处理器中定义了对应的捕获器,就会在操作发生时被触发;否则,操作会默认直接作用于目标对象。Proxy 机制被广泛用于框架和库中,比如 Vue3 的响应式系统就是基于 Proxy 实现的
get 和 set 捕获器详解
在 handler
中可以定义不同的捕获器来拦截操作。其中最常用的是 get
和 set
:
-
get(target, property, receiver):拦截属性读取操作,当访问
proxy.property
时触发。参数说明为-
target
:目标对象(被代理的原始对象)。 -
property
:被读取的属性名。 -
receiver
:通常是当前访问该属性时的this
值(通常就是代理对象本身,或者如果继承自该代理的对象,则是继承对象)。如果该属性是一个 getter,那么receiver
就是执行 getter 时的this
。
-
-
set(target, property, value, receiver):拦截属性写入操作,当执行
proxy.property = value
时触发。参数说明为target
:目标对象。-
property
:被写入的属性名。 -
value
:写入的值。 -
receiver
:与get
类似,对应 setter 被调用时的this
。
set
捕获器应该返回一个布尔值,true
表示写入成功,false
表示失败(失败时会抛出TypeError
)
-
例如,以下代码演示了一个带有 get
和 set
捕获器的 Proxy 用法:
const person = {name: "张三",get aliasName() {return this.name + "handsome";},
};
const proxyPerson = new Proxy(person, {get(target, key, receiver) {console.log("get", key);return Reflect.get(target, key, receiver);},set(target, key, value) {console.log(`set ${key} = ${value}`);return Reflect.set(target, key, value);},
});
console.log(person.aliasName); // 张三handsome
console.log(proxyPerson.aliasName); // 输出:get aliasName \n 张三handsome
proxyPerson.name = "李四"; // 输出:set name = 李四
console.log(proxyPerson.aliasName); // 输出:get aliasName \n 李四handsome
上例中&#