代码之家  ›  专栏  ›  技术社区  ›  Nishant Florentin

用javascript装饰函数

  •  0
  • Nishant Florentin  · 技术社区  · 6 年前

    下面是一个修改普通函数的简单decorator模式:

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

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

    我不能直接用这个模式来装饰绑定函数 obj.prop 因为如果我把它作为 decorator ,它不会使用 wrapper 因为javascript依赖于 打电话 传递正确的对象。所以 obj.prop() 有上下文意识,但是 对象属性 不是。有办法克服这个限制吗?

    如果不可能,我需要:

    更改模式以接受对象和属性作为两个不同的参数并使其工作。

    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 回复  |  直到 6 年前
        1
  •  2
  •   Bergi    6 年前

    你可以用 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); 会有用的。