当传递方法作为回调时,Coffeescript的@范围不正确

时间:2015-05-15 09:03:32

标签: javascript coffeescript

当我将带有胖箭头的匿名函数作为socket.io回调传递,然后在同一对象中调用另一个方法(如下所示)时,@的范围是正确的:

module.exports = class InviteCreateSocket extends AbstractSocket
  register: () ->
    @socket.on 'invite:create', (data, callback) => @create data, callback

  create: (data = {}, callback = @_noop) ->
    # This returns an instantiated InviteCreateSocket. Bonzer!
    console.log @

但是,如果我直接传递它,则范围现在是套接字,就像我使用细箭头运行前面的代码一样:

module.exports = class InviteCreateSocket extends AbstractSocket
  register: () ->
    @socket.on 'invite:create', @create

  create: (data = {}, callback = @_noop) ->
    # This returns the socket. Not bonzer. Not bonzer at all.
    console.log @

那么,有没有一个很好的方法来获取对象范围而不必通过胖匿名函数来中继它们?第一种方法有效,但看起来有点笨拙,显然需要同步参数在所有方法中。提前谢谢!

2 个答案:

答案 0 :(得分:3)

为什么不对属于该类的函数使用胖箭头,从而将它们正确地绑定到类的上下文(以及它的实例) - 这就是它的工作方式。

module.exports = class InviteCreateSocket extends AbstractSocket
  register: () =>
    @socket.on 'invite:create', @create
    return

  create: (data = {}, callback = @_noop) =>
    console.log @
    return

另外,不要忘记在函数中添加空返回值,这些返回值不是为了返回某些内容。

答案 1 :(得分:2)

不是Coffeescript专家,但我猜不是。这是因为Coffeescript被编译为JavaScript,并且JavaScript等同于你。问题在于:您无法引用方法,因为必须在接收方上调用方法。

var bar = foo.create;
bar();

非常不同
foo.create();

因为前者没有将this设置为foo。因此,当您刚刚通过@create时,它会将您的方法与您的对象分离,并且@在您的方法中不再正确 - 这就是现在只是一个功能。

现在,回到CoffeeScript:解决参数困境的最有效方法是=> @create(arguments...)。这应该将所有参数传递给@create,无论它们是什么。但是,更好的方法是使用简单的JS技术模拟胖箭头的作用:@create.bind(@)

但是,在CoffeeScript中更有知识的人可能会有更好的事情。