是否有可能提前改变任何对象方法的行为?

时间:2017-03-04 23:18:01

标签: javascript

我需要实现以下目标:如果有人访问对象foo()的方法obj(执行obj.foo()),那么会发生obj.bar("foo")

在这个实际场景中,我可以通过简单地为obj.foo定义一个getter来实现这一点:

Object.defineProperty(obj, "foo", {
    get: () => obj.bar("foo")
});

但是,是否有可能提前为每个方法做到这一点(即使是尚未定义的方法)?我的意思是不为每一种方法提供吸气剂。

我现在可以看到的最佳解决方案是在obj完全定义之后迭代所有方法:

for (let methodName in obj)
    if (typeof obj[methodName] === "function" && methodName !== "bar")
        Object.defineProperty(obj, methodName, {
            get: () => obj.bar(methodName)
        });

另一个是用一个重复的代码行开始每个方法 - 这是令人不愉快的。

是否存在没有迭代或自我重复的解决方案?

1 个答案:

答案 0 :(得分:3)

在现代Javascript中执行此操作的方法是使用Proxy对象。

这能够(除其他外)将对象的所有属性访问转发给处理程序。

所以我们可以这样做:

let origin = {
    bar(word) {
        console.log('bar: ', word);
    }
};

// wrap the origin object in a Proxy handler
let p = new Proxy(origin, {
    get(target, prop) {
        // wrap the value in a function
        return () => target.bar(prop);
    }
});

p.foo(); // outputs "bar: foo"

请注意,这假设您要p.foo(),而不仅仅是p.foo。它在函数中包含您想要的值。即使房产实际存在,它也会转发房产权。