【发布时间】:2019-12-10 20:35:54
【问题描述】:
我正在创建一个虚拟化对象,该对象使用规则引擎延迟构建其属性,作为一种跳过计算从未读取的值的技术。为此,我使用了Proxy。代理似乎为访问转发和虚拟化提供双重职责。就我而言,我主要关心的是后者,而不是前者。
我遇到的问题与尝试在代理中实现 getOwnPropertyDescriptor 陷阱有关。这样做时我收到错误:
TypeError:代理上的“getOwnPropertyDescriptor”:陷阱返回的属性“foo”的描述符与代理目标中的现有属性不兼容
因为我实际上并没有将请求转发到包装对象,所以我一直使用Object.freeze({}) 作为传递给new Proxy(...) 的第一个参数。
function createLazyRuleEvaluator(rulesEngine, settings) {
const dummyObj = Object.freeze({});
Object.preventExtensions(dummyObj);
const valueCache = new Map();
const handlers = {
get(baseValue, prop, target) {
if (valueCache.has(prop))
return valueCache.get(prop);
const value = rulesEngine.resolveValue(settings, prop);
valueCache.set(prop, value);
return value;
},
getOwnPropertyDescriptor(baseValue, prop) {
return !propIsInSettings(prop, settings) ? undefined : {
configurable: false,
enumerable: true,
get() {
return handlers.get(baseValue, prop, null);
}
};
},
};
return new Proxy(dummyObj, handlers);
}
// This throws
Object.getOwnPropertyDescriptor(createLazyRuleEvaluator(/*...*/), 'foo');
代理对象旨在类似于具有只读属性的对象,该属性无法扩展或具有任何其他此类幻想。我尝试使用冻结且不可扩展的对象,但我仍然被告知属性描述符不兼容。
当我尝试使用非冻结对象作为代理目标时,我得到一个不同的类型错误:
TypeError:代理上的“getOwnPropertyDescriptor”:陷阱报告属性“foo”的不可配置性,该属性在代理目标中不存在或可配置
我在这里做错了什么?有什么方法可以让我的代理显示不可配置性?
【问题讨论】:
-
"我实际上并没有将请求转发到一个包装的对象" - 是的。您没有为其编写陷阱处理程序的所有请求仍会转发到对象,例如
has或set。 -
不,我不是。发布的代码不完整(我正在使用 TDD 并遇到了这个问题)。我将实现所有的陷阱处理程序。
标签: javascript es6-proxy