Coffeescript:从同一对象中的函数调用数组函数

Coffeescript: Calling array functions from a function in the same object

我正在尝试为 Atom 文本编辑器编写一个包,在我的主 class (init.coffee) 中,我的 module.exports 中有一个数组:

servers: []

我想从 module.exports 另一部分的函数访问此数组,但我遇到了问题。

函数:

stas: () ->
    dir = getFilePath()
    d = fs.statSync dir
    if !d.isDirectory()
        dirError dir
    else
        s = new Server dir
        s.init()
        @servers.push s
    return

我不断收到此错误:

Uncaught TypeError: this.servers.push is not a function

我这样调用函数:

@events.add atom.commands.add ".tree-view", {
  'atom-together:startServer': @stas
  'atom-together:startClient': @stac
  'atom-together:stopServer': @stos
  'atom-together:stopClient': @stoc
}

在 coffeescript 中调用这个数组的正确方法是什么?

JavaScript/CoffeeScript 函数中 this(又名 @)的值通常取决于它的调用方式,而不是它的定义位置。此外,@stas 只是对 stas 函数的引用,而 this 将是调用该函数时调用者希望它成为的任何内容。

如果您在回调函数中需要特定的 @(又名 this),则可以将其定义为 bound function:

stas: () => # Note the => instead of ->
  #...

或在将其传递给事件系统时使用 Function.prototype.bind 绑定它:

@events.add atom.commands.add ".tree-view", {
  'atom-together:startServer': @stas.bind(@)
  #...
}

此外,如果您像这样在 class 级别定义 servers: []

class C
  servers: []

那么您将在 class 的所有实例之间共享一个 servers 数组,而这可能不是您想要的。在 class 级别定义的事物通过原型在所有实例之间共享。例如:

class C
  a: [ ]

c1 = new C
c2 = new C
c1.a.push 11
console.log c1.a, c2.a

会在控制台中放两个[11]因为c1.ac2.a是同一个数组。您通常最好在 constructor 中定义可变值以避免这种共享(除非您特别希望它发生);这个版本:

class C
  constructor: (@a = [ ]) ->

c1 = new C
c2 = new C
c1.a.push 11
console.log c1.a, c2.a

会在控制台中为您提供 [11][],这通常是您正在寻找的行为。