我有一个简单的代理对象:
const myProxy = new Proxy(
/* myTarget */
{
test: 2,
},
/* myHandler */
{
get(target, prop, proxy)
{
if (prop in this && this[prop] instanceof Function)
return this[prop](target); //getter
return target[prop]; //value
},
myGetter(target)
{
return ++target.test
}
}
);
console.log("test before", myProxy.test);
console.log("myGetter", myProxy.myGetter);
console.log("test after", myProxy.test);
有没有办法让myGetter
财产成为真正的吸气剂?我的尝试失败了,因为我不知道如何myTarget
从 getter 中访问:
const myProxy = new Proxy(
/* myTarget */
{
test: 2,
},
/* myHandler */
{
get(target, prop, proxy)
{
if (prop in this)
return this[prop]; //getter
return target[prop]; //value
},
get myGetter()
{
return ++target.test; //target undefined
}
}
);
console.log("test before", myProxy.test);
console.log("blah", myProxy.myGetter);
console.log("test after", myProxy.test);
我需要这个的原因是因为我在处理程序中有多个函数,我需要确定哪一个需要在处理程序本身内执行(myGetter
),或者应该作为函数引用(myFunc
)返回,它还可以接受额外的数据作为参数,所以我prop instanceof Function
用来检查它是否是一个函数:
const myProxy = new Proxy(
/* myTarget */
{
test: 2,
},
/* myHandler */
{
get(target, prop, proxy)
{
if (prop in this)
{
if (this[prop] instanceof Function)
return (args) => this[prop](target, args); //function
return this[prop]; //getter
}
return target[prop]; //value
},
get myGetter()
{
return ++target.test; //target undefined
},
myFunc(target, value)
{
return target.test * value;
}
}
);
console.log("myFunc", myProxy.myFunc(3));
console.log("test before", myProxy.test);
console.log("myGetter", myProxy.myGetter);
console.log("test after", myProxy.test);
我可以想到几种解决方法,例如函数的硬代码名称:
const myProxy = new Proxy(
/* myTarget */
{
test: 2,
},
/* myHandler */
{
get(target, prop, proxy)
{
if (prop in this)
{
if (["myFunc"].includes(prop)) // function
return (args) => this[prop](target, args);
return this[prop](target); // getter
}
return target[prop];
},
myGetter(target)
{
return ++target.test
},
myFunc(target, value)
{
return target.test * value;
}
}
);
console.log("myFunc", myProxy.myFunc(3));
console.log("test before", myProxy.test);
console.log("myGetter", myProxy.myGetter);
console.log("test after", myProxy.test);
或将功能分成组:
const myProxy = new Proxy(
/* myTarget */
{
test: 2,
},
/* myHandler */
{
get(target, prop, proxy)
{
if (prop in this._myFuncs)
return (args) => this._myFuncs[prop](target, args);
if (prop in this._myGetters)
return this._myGetters[prop](target);
return target[prop];
},
_myGetters:
{
myGetter(target)
{
return ++target.test
},
},
_myFuncs:
{
myFunc(target, value)
{
return target.test * value;
},
}
}
);
console.log("myFunc", myProxy.myFunc(3));
console.log("test before", myProxy.test);
console.log("myGetter", myProxy.myGetter);
console.log("test after", myProxy.test);
出于教育目的,有什么建议可以让真正的吸气剂在 Proxy 中工作吗?
我认为处理程序对象上不应该有非标准的属性——它只具有预期具有的陷阱会更有意义。要收集陷阱的属性,要么对这些属性进行硬编码(不灵活且不太好),要么为这些属性使用单独的对象结构。在代理闭包中使用一个单独的对象,检查该属性是否存在于该对象上,然后.call
如果它是一个 getter,则使用 target 对其进行操作很容易。
const makeProxy = (target, customProperties) => {
return new Proxy(
target, {
get(target, prop, proxy) {
if (prop in customProperties) {
// Invoke getter if it exists on customProperties
const { get } = Object.getOwnPropertyDescriptor(customProperties, prop);
if (get) {
return get.call(target);
}
}
// Otherwise return original object value or getter
return target[prop];
},
}
);
};
const proxy = makeProxy({
test: 2,
}, {
get myGetter() {
return ++this.test
}
});
console.log("test before", proxy.test);
console.log("blah", proxy.myGetter);
console.log("test after", proxy.test);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句