The Reflect API in JavaScript
What the Reflect object provides, how its methods mirror Proxy traps, and why it's the right way to forward operations inside a proxy.
Reflect 把对象的基本操作变成函数调用——原来 obj.name 是一种语法糖,Reflect.get(obj, 'name') 则是显式调用底层的 [[GET]] 方法。
为什么要这样?因为语法糖在使用时做了一些隐式假设,有时候会让人困惑。
比如说有这么一个对象,
1
2
3
4
5
6
const obj = {
a: 1,
get b() {
return this.a + 1;
},
};
在使用 obj.b 的时候,实际上还是调用了 [[GET]],方法,注意它有个属性 Receiver,obj.b 就是默认了 Receiver 就是 obj 本身,导致了 this 是指向 obj 的。因此,this.a就等于 1。
如果使用 Reflect.get(obj, 'b') 的话,可以手动指定 Receiver,这样就不会再使用默认的 this 了。
1
2
3
4
5
6
7
const obj = {
a: 1,
get b() {
return this.a + 1;
},
};
console.log(Reflect.get(obj, "b", { a: 9 })); // 10
这时,this 是指向 {a: 9},所以 this.a 等于 9,所以 obj.b 等于 10。
需要灵活控制对象操作时——比如在 Proxy 的 handler 里转发操作、或者需要自定义 this 指向——用 Reflect 比直接 obj.xxx 更精确。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
};
Reflect.get(myObject, "foo"); // 1
Reflect.get(myObject, "bar"); // 2
Reflect.get(myObject, "baz"); // 3
const myReceiverObject = {
foo: 4,
bar: 4,
};
Reflect.get(myObject, "baz", myReceiverObject); // 8
Reflect 还有很多的「静态方法」,比如 Reflect.apply()、Reflect.has()、Reflect.ownKeys() 等等,可以查看ECMA 262 文档或MDN 文档了解更多。
This post is licensed under CC BY 4.0 by the author.