如何自动包装类的所有方法?

时间:2012-06-10 17:06:41

标签: javascript methods coffeescript wrapper

为了简化调试coffeescript应用程序,我希望有一个logWrapClass(Klass)函数,使用方法包装器自动为我的类中的方法添加console.log(method.name, method.arguments),这是可行的吗?

这似乎不够

consoleLogWrapClass = (Klass) ->
  klassName = Klass.toString()
  klassName = klassName.substr 'function '.length
  klassName = klassName.substr 0, klassName.indexOf('(')

  K = Klass.prototype
  for prop of K #in Object.getOwnPropertyNames(K)
    obj = K[prop]
    if typeof(obj) is 'function'
      decoratedName = "#{klassName}::#{prop}"
      K[prop] = () ->
        console.debug 'trace: '+decoratedName, arguments
        return obj.apply this, arguments

当我做的时候

class Someclass
    ...

consoleLogWrapClass Someclass

看起来包装器已经混淆了初始类的所有函数,就像所有obj和decoratedName由于某种原因指向同一个元素一样。

编辑:好吧,现在甚至更奇怪了,因为如果我将调用分成两个函数

consoleLogWrapFunction = (fn, decoratedName) ->
  () ->
    console.debug 'trace: '+decoratedName, arguments
    return fn.apply this, arguments

consoleLogWrapClass = (Klass) ->
  klassName = Klass.toString()
  klassName = klassName.substr 'function '.length
  klassName = klassName.substr 0, klassName.indexOf('(')

  K = Klass.prototype
  for prop of K #in Object.getOwnPropertyNames(K)
    obj = K[prop]
    if typeof(obj) is 'function'
      K[prop] = consoleLogWrapFunction obj, "#{klassName}::#{prop}"

它有效,有人可以解释原因吗?

2 个答案:

答案 0 :(得分:1)

consoleDebugWrapFunction = (name, fn) ->
  ->
    console.log "#{name} called with arguments: #{[].slice.call(arguments).join ', '}"
    fn.apply this, arguments

consoleDebugWrapClass = (Klass) ->
  for prop of Klass.prototype
    obj = Klass.prototype[prop]
    if typeof obj is 'function'
      Klass.prototype[prop] = consoleDebugWrapFunction prop, obj

用法示例:

class A
  foo: (a, b) ->
    a + b

consoleDebugWrapClass A
a = new A
console.log a.foo 3, 6

输出:

foo called with arguments: 3, 6
9

答案 1 :(得分:0)

也许这次审计有帮助

How to implement a simple prioritized listener pattern in JavaScript

您可以使用该技术并包装所有原型成员

function wrap(o,f) {for(var n in o) if (typeof(n)=="function") o[n]=f.prefix(o[n]);}

o =要包裹的对象

f =审计职能