如何在coffeescript中编写一个围绕另一个函数的函数?
假设我想包装一个任意函数来添加日志记录之类的内容(或其他内容)。包装器应该是通用的,适用于任何如何在coffeescript中编写一个围绕另一个函数的函数?,coffeescript,Coffeescript,假设我想包装一个任意函数来添加日志记录之类的内容(或其他内容)。包装器应该是通用的,适用于任何f,可以用任何类型的参数调用 createWrapper= (f) -> wrapper= -> # do the logging or whatever I want before I call the original result= ??? # do whatever after the original function call re
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)
现在我可以在任何地方使用g
,只要我想使用f
,但它会调用我的包装函数
我的问题是:我应该如何调用f
来获得结果?只需运行f()
答案是
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
或者,如果您想更明确一点,可以使用。
这样做的好处是参数是一个列表,您可以应用
列出对参数的操作
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
以下是一些测试:
我的猜测是:
f.apply@,arguments
你的猜测是正确的:)。这是一本关于JS装饰器函数的好读物(将其翻译成CS应该没有问题):我想要传递给f的参数——我应该让我的问题更清楚。。。
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
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]}
""")