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

Coffeescript incorrect scope of @ when passing method as callback

当我将带有粗箭头的匿名函数作为 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 @

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

不是 Coffeescript 专家,但我猜不是。这是因为 Coffeescript 被编译为 JavaScript,而 JavaScript 等效项对您不利。问题是:您不能引用方法,因为要成为方法,必须在接收者上调用它。

var bar = foo.create;
bar();

非常不同
foo.create();

因为前者没有将this设置为foo。因此,当您仅传递 @create 时,它会将您的方法与您的对象分离,并且 @ 在您的方法中不再正确,即现在只是一个函数。

现在,回到 CoffeeScript:解决参数难题的更丑陋的方法是 => @create(arguments...)。这应该将所有参数传递给 @create,无论它们是什么。然而,更好的方法是使用普通 JS 技术模拟粗箭头的作用:@create.bind(@).

不过,如果有人更了解 CoffeeScript,可能会有更好的东西。

为什么不对属于 class 的函数使用粗箭头,从而将它们正确地绑定到 class 的上下文(及其实例)——这更符合预期上班。

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

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

另外,不要忘记在函数中添加空的 returns,这些 returns 不是为了 return 某些东西。