【问题标题】:How to write a function in coffeescript that wraps around another function?如何在咖啡脚本中编写一个包含另一个函数的函数?
【发布时间】:2013-07-29 02:00:47
【问题描述】:

假设我想包装一个任意函数来添加诸如日志记录(或其他任何东西)之类的东西。包装器应该是通用的并且适用于任何可以使用任何类型的参数调用的f

createWrapper= (f) ->
   wrapper= -> 
     # do the logging or whatever I want before I call the original
     result= ???
     # do whatever after the original function call
     result

用法如下:

g=createWrapper(f)

现在应该以任何方式调用g f,就像

result = g(1,2,3)

应该返回相同的

result = f(1,2,3)

现在我可以在任何我想使用f 的地方使用g,但它会调用我的包装函数。

我的问题是:我应该如何调用f 来获得结果?

【问题讨论】:

标签: coffeescript


【解决方案1】:

答案是

f.apply @, arguments

因此包装器看起来像

createWrapper= (f) ->
   -> 
     # do the logging or whatever I want before I call the original
     result= f.apply @, arguments
     # do whatever after the original function call
     result

或者如果你不想在通话后做任何事情

createWrapper= (f) ->
   -> 
     # do the logging or whatever I want before I call the original
     f.apply @, arguments

或者如果你想更明确一点,你可以使用splat。 这样做的好处是参数是一个列表,您可以应用 列出对参数的操作。

createWrapper= (f) ->
   (args...) -> 
     # do the logging or whatever I want before I call the original
     result= f.apply @, args
     # do whatever after the original function call
     result

这是一些测试code

createWrapper= (f) ->
   (args...) -> 
     # do the logging or whatever I want before I call the original
     result= f.apply @, args
     # do whatever after the original function call
     result

class cl
   i: 10
   f: (x) ->
     x + @i
   getf: (x) ->
     (x)=>@f(x)

c =new cl
f1 = c.getf()
g1 = createWrapper(f1)
if f1(1)!=g1(1)
   throw new Error("failed f1 #{f1 1} != #{g1 1}")

f2 = (x) -> x+20
g2 = createWrapper(f2)
if f2(1)!=g2(1)
   throw new Error("failed f2 #{f2 1} != #{g2 1}")


f3 = (args...) -> "#{args}"
g3 = createWrapper(f3)
if f3(1,2,3)!=g3(1,2,3)
   throw new Error("failed f3 #{f3 1,2,3} != #{g3 1,2,3}")

f4 = -> arguments[0]
g4 = createWrapper(f4)
if f4(1)!=g4(1)
   throw new Error("failed f4 #{f4 1} != #{g4 1}")

f5 = c.f
g5 = createWrapper(f5)
if f5.apply(c,[1])!=g5.apply(c,[1])
   throw new Error("failed f5 #{f5.apply c,[1]} 1= #{g5.apply c,[1]}")

alert("""
Everything is OK:
   f1 #{f1 1} == #{g1 1} 
   f2 #{f2 1} == #{g2 1} 
   f3 #{f3 1,2,3} == #{g3 1,2,3} 
   f4 #{f4 1} == #{g4 1} 
   f5 #{f5.apply c,[1]} == #{g5.apply c,[1]} 
""")

【讨论】:

    【解决方案2】:

    只需运行 f()

    createWrapper = (f) ->
      wrapper= -> 
        # do the logging or whatever I want before I call the original
        result= f()
        # do whatever after the original function call
        result
    

    【讨论】:

    • 我想要传递给 f 的参数——我应该让我的问题更清楚......
    猜你喜欢
    • 2012-09-03
    • 2015-12-24
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多