无法理解为什么我应该使用
Reflect.get(obj, 'foo')
而不是 obj['foo']
,或者为什么第一个很有用,因为我们可以使用良好且旧的对象括号表示法做同样的事情。有人可以详细说明一下吗?
var obj = {foo: 'bar'};
obj['foo'];
Reflect.get(obj, 'foo');
嗯,对你的问题的迂腐答案是它们完全不同:属性访问器返回属性的引用,而
Reflect.get
返回其值。
从实际角度来看,这没有任何区别,因为属性引用总是在右侧取消引用。
Reflect.get
的一个实际用法是使用它的第三个参数,当与Proxy
结合使用时,可以用于创建相同数据的不同“视图”。
let numbersView = obj => new Proxy(obj, {
get(target, key, receiver) {
return receiver(target[key])
}
});
let decimal = x => String(x);
let english = x => {
if (x === 1) return 'one';
if (x === 2) return 'two';
};
let v = numbersView({
a: 1,
b: 2
});
console.log(Reflect.get(v, 'a', decimal))
console.log(Reflect.get(v, 'a', english))
这个例子有点虚构,但你已经明白了。
return Reflect.get(...arguments);
Reflect.get
指吸气剂(如果有的话)。 foo
getter 被赋予代理对象 receiver
(receiver === case1
),用于其 this
。意思是,也调用了 get
的 bar
陷阱。
const case1 = new Proxy({
get foo() {
console.log("The foo getter", this);
return this.bar;
},
bar: 3
}, {
get(target, property, receiver) {
console.log("The Proxy get trap", ...arguments);
return Reflect.get(...arguments);
}
});
console.log(case1.foo);
> case1.foo
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The foo getter ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶bar ▶Proxy {bar: 3}
▶3
return target[property];
使用未代理的对象,
target
。这也会触发 foo
getter,但请注意:this
getter 的 foo
是未代理的对象 target
。未调用 get
的 bar
陷阱。
const case2 = new Proxy({
get foo() {
console.log("The foo getter", this);
return this.bar;
},
bar: 3
}, {
get(target, property, receiver) {
console.log("The Proxy get trap", ...arguments);
return target[property];
}
});
console.log(case2.foo);
> case2.foo
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The foo getter ▶{bar: 3}
▶3
return receiver[property];
使用代理对象,
receiver
(receiver === case3
)。 receiver[property]
指的是get
陷阱,而不是吸气剂,导致无限循环。
const case3 = new Proxy({
get foo() {
console.log("The foo getter", this);
return this.bar;
},
bar: 3
}, {
get(target, property, receiver) {
console.log("The Proxy get trap", ...arguments);
return receiver[property];
}
});
console.log(case3.foo);
> case3.foo
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
▶The Proxy get trap ▶{bar: 3} ▶foo ▶Proxy {bar: 3}
……
Uncaught RangeError: Maximum call stack size exceeded
现在你明白了。
不明白为什么我应该使用
而不是Reflect.get(obj, 'foo')
obj['foo']
虽然使用
Reflect
动词是 Proxy
陷阱实现的惯用法,但实际上没有 should。这取决于您的用例。如果您的 target
(“未代理”)对象没有 getter,或者您对其 getter 正在访问的属性(“辅助属性访问”)不感兴趣,那么您可能不需要看起来很花哨的 Reflect
。另一方面,如果您想触发所有类型的属性访问(主要或次要)的陷阱,您将需要 Reflect
。
对于我来说,我始终坚持
return Reflect.get(...arguments);
。