Reflect API
使用 Reflect 方法转发操作。
Reflect API 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。
什么是 Reflect
Reflect 是一个内置对象,其中的方法可以对对象执行默认的底层操作,例如获取、设置和删除等。
它的方法与代理拦截器一一对应,因此非常适合用于编写正确的代理对象。
Reflect.get
Reflect.get(target, prop) 会读取属性,作用与 target[prop] 相同,但形式上是一次简洁的函数调用。
const obj = { name: 'Ada', age: 36 };
console.log(Reflect.get(obj, 'name'));
console.log(Reflect.get(obj, 'age'));Reflect.set
Reflect.set(target, prop, value) 会写入属性,并返回 true 或 false 表示是否成功,就像 set 拦截器所要求的那样。
const obj = {};
const ok = Reflect.set(obj, 'score', 42);
console.log(ok);
console.log(obj.score);Reflect.has 和 deleteProperty
Reflect.has 与 in 运算符对应,Reflect.deleteProperty 与 delete 操作对应;二者都是返回布尔值的函数。
const obj = { a: 1, b: 2 };
console.log(Reflect.has(obj, 'a'));
console.log(Reflect.deleteProperty(obj, 'b'));
console.log(Reflect.has(obj, 'b'));Reflect.ownKeys
Reflect.ownKeys 会返回所有自有属性键,包括符号键和不可枚举属性,比 Object.keys 更完整。
const obj = { a: 1, b: 2 };
Object.defineProperty(obj, 'hidden', { value: 3, enumerable: false });
console.log(Object.keys(obj));
console.log(Reflect.ownKeys(obj));在代理中转发操作
真正强大的地方在于:在拦截器内部调用对应的 Reflect 方法来执行默认行为,然后在其周围添加自定义逻辑。
const proxy = new Proxy({ v: 1 }, {
get(target, prop, receiver) {
console.log('reading ' + prop);
return Reflect.get(target, prop, receiver);
}
});
console.log(proxy.v);正确转发 set
在 set 拦截器内部使用 Reflect.set 会自动返回正确的布尔值,因此您不必记得自行返回 true。
const proxy = new Proxy({}, {
set(target, prop, value, receiver) {
console.log('writing ' + prop);
return Reflect.set(target, prop, value, receiver);
}
});
proxy.x = 10;
console.log(proxy.x);receiver 为何重要
将 receiver 传给 Reflect.get 和 Reflect.set,可以确保访问器和设置器在正确的 this 环境中运行。当对象彼此继承时,这一点非常重要。
const base = { get label() { return 'id-' + this.id; } };
const proxy = new Proxy(base, {
get(target, prop, receiver) {
return Reflect.get(target, prop, receiver);
}
});
const child = Object.create(proxy);
child.id = 7;
console.log(child.label);Reflect.apply
Reflect.apply(fn, thisArg, argsArray) 会使用给定的 this 和参数数组调用函数,是 fn.apply 更简洁的替代方案。
function greet(greeting, name) {
return greeting + ', ' + name;
}
console.log(Reflect.apply(greet, null, ['Hello', 'Ada']));Reflect.construct
Reflect.construct(Cls, argsArray) 会创建一个实例,作用等同于 new Cls(...args),但使用的是参数数组。
class Point {
constructor(x, y) { this.x = x; this.y = y; }
}
const p = Reflect.construct(Point, [3, 4]);
console.log(p.x, p.y);Reflect 为何重要
Reflect 提供了对象内部操作的函数形式和可预测版本,并且与代理对象完美配合:每个拦截器都会将操作转发给对应的 Reflect 方法。这样就能得到正确且简洁的代理代码。接下来您将把这些知识应用到实际使用场景中。
const audited = new Proxy({ balance: 100 }, {
set(t, p, v, r) {
console.log(p + ': ' + t[p] + ' -> ' + v);
return Reflect.set(t, p, v, r);
}
});
audited.balance = 150;
console.log(audited.balance);快速检查
在 get 拦截器内部,为什么要调用 Reflect.get(target, prop, receiver),而不是使用 target[prop]?
回顾:Reflect 接口
您学会了 Proxy 的搭档:
Reflect提供函数形式的默认操作:get、set、has、deleteProperty和ownKeys。- 它的方法与代理拦截器一一对应。
- 通过带有
receiver的Reflect进行转发,可以确保继承关系正确。 Reflect.apply和Reflect.construct可以简洁地调用函数和创建实例。
常见问题解答
「Reflect API」课时是免费的吗?
是的 — 「Reflect API」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。
「Reflect API」这节课中我会学到什么?
使用 Reflect 方法转发操作。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 JavaScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「Reflect API」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 JavaScript Academy 课中编写并运行代码吗?
能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 创建 Proxy
- get 和 set 陷阱
- Reflect API
- Proxy 的实际应用场景