用JavaScript装饰函数

时间:2018-06-02 09:57:10

标签: javascript decorator

这是一个简单的装饰器模式,它修改了一个正常的函数:

function decorator1(f){
   function wrapper(...args){
       pre();
       return f(...args);
       post();
   }
   return wrapper
}

现在假设有一个对象obj,它的原型中有一个属性prop。我想出于某种原因修改对象的绑定函数。

我无法直接使用此模式来修饰绑定函数obj.prop,因为如果我将它作为参数传递给decorator,它将无法使用正确的方法调用wrapper中的对象,因为JavaScript依赖于调用来传递正确的对象。因此obj.prop()是上下文感知的,但obj.prop不是。有没有办法克服这个限制?

如果不可能,我需要:

更改模式以将对象和属性接受为2个不同的参数并使其有效。

function decorator2(o, f){
   function wrapper(...args){
       pre();
       return o.f(...args);
       post();
   }
   return wrapper
}

obj.prop = decorator2(obj, prop);

传递一个绑定函数,由于某种原因,我认为这是一个硬编码。

// This creates a bound function to itself.
obj.prop = obj.prop.bind(obj)
// This modifies it.
obj.prop = decorator1(obj.prop)

哪一个更受欢迎?我会选择前者,因为我认为创建绑定函数并不好,除非你真的需要它们。

1 个答案:

答案 0 :(得分:1)

您可以在this

中使用wrapper
function decorate(f) {
    return function wrapper(...args) {
        pre();
        const res = f.apply(this, args); // or f.call(this, ...args)
//                          ^^^^
        post();
        return res; // make post() work
    };
}

有了这个,普通obj.prop = decorate(obj.prop);就可以了。