首页 > 解决方案 > Javascript 匿名装饰器

问题描述

装饰器是否可以保留包装的函数引用?

除了以下代码之外,我不确定如何解释这个问题:

这是一个最小的例子,它没有意义,但在上下文中它确实

const myObject = {
  myFunction : function(txt) {
    this.myOtherFunction(txt)
  },
  
  myOtherFunction : function(txt) {
    console.log(txt)
  }
}

function decorator(wrapped) {
  return function() {
    return wrapped.apply(this, arguments)
  }
}

//Works
myObject.myFunction('Hello')
//But decorated it doesn't work
decorator(myObject.myFunction)('Hello')

标签: javascript

解决方案


返回的函数decorator期望使用特定this对象调用它,并使用该对象调用该wrapper函数。由于包装器 ( myObject.myFunction) 的正确功能取决于传递正确的this对象,因此您必须确保decorator使用该this绑定进行调用。

所以这将起作用:

decorator(myObject.myFunction).call(myObject, 'Hello') 

或者,您可以将一个函数传递给具有正确this绑定的装饰器:

decorator(myObject.myFunction.bind(myObject))('Hello')

替代方案:不this依赖

如果你让你的对象方法独立于this. 有几种方法可以做到这一点,但这里有一种:

const myObject = (function () {
   function myFunction(txt) {
       myOtherFunction(txt);
   }
   function myOtherFunction(txt) {
       console.log(txt);
   }
   return { myFunction, myOtherFunction };
})(); // IIFE

function decorator(wrapped) {
  return function() {
    return wrapped.apply(this, arguments)
  }
}

//Works
myObject.myFunction('Hello')
//Also works
decorator(myObject.myFunction)('Hello')

替代方案:方法的特定装饰器功能

您可以创建一个单独的装饰器函数,它需要两个参数:一个对象和方法的名称(一个字符串):

const myObject = {
  myFunction : function(txt) {
    this.myOtherFunction(txt)
  },
  
  myOtherFunction : function(txt) {
    console.log(txt)
  }
}

function methodDecorator(obj, methodName) {
  return function() {
    return obj[methodName].apply(obj, arguments)
  }
}

//Works
myObject.myFunction('Hello')
//Also works
methodDecorator(myObject, "myFunction")('Hello')


推荐阅读