如何创建一个包罗万象的对象代理?

时间:2018-08-16 15:14:09

标签: javascript

我想创建一个代理对象,该对象拦截所有属性检索和函数调用,并返回undefined

完成前者是微不足道的:

const proxy = new Proxy({}, { get: () => undefined });
proxy.foo // undefined

事实上,我什至不需要代理,一个空对象({})也会这样做。但是,对函数调用执行相同操作会引发错误:

proxy.foo() // TypeError: proxy.foo is not a function

我可以让get陷阱返回一个函数:

const proxy = new Proxy({}, { get: () => () => undefined });
proxy.foo() // undefined
proxy.foo // [Function]

但是如您所见,对于我的原始属性访问案例,它将返回一个函数,而不是undefined。有可能完成我想要的吗?

const proxy = ???;
proxy.foo; // undefined
proxy.foo(); // undefined

最终目标是将其用作测试的“全包”存根。

更新: 感谢@Bergi的回答。以下代码完成了我想要的:

const proxy = new Proxy(new Function, {
  get: (target, prop, receiver) => receiver,
});

console.log('proxy.foo', proxy.foo); // undefined
console.log('proxy.foo()', proxy.foo()); // undefined
console.log('proxy.foo.bar', proxy.foo.bar); // undefined
console.log('proxy.foo.bar()', proxy.foo.bar()); // undefined

2 个答案:

答案 0 :(得分:1)

否,这是不可能的。代理不拦截方法调用,它只能拦截对代理本身的调用(如proxy())。方法调用只是对属性值的访问,随后是对属性值的函数调用。并且不可能同时具有undefined和函数的值。

要拥有一个真正的万能存根进行测试,您的代理应返回自己(或者更好的是另一个代理)以进行任何访问或调用,以便您可以拥有任意链。

答案 1 :(得分:0)

只需实现您想要的,就可以做到。

var obj = {
    foo: 1,
    bar: 2,
    fooFunc: () => {
        return "this is fooFunc";
    },
    barFunc: () => {
        return "this is barFunc";
    }
}

let Proxy = function (object) {

    for(var prop in object) {
        if(typeof object[prop] === 'function') {
            this[prop] = () => {
                return undefined;
            }
        }
        else {
            this[prop] = undefined;
        }
    }
}

let proxy = new Proxy(obj);

console.log(obj.foo);
console.log(proxy.foo);

console.log(obj.fooFunc());
console.log(proxy.fooFunc());

这不是自定义存根方法的理想选择,但我认为这种方法适用于您的情况。