CoffeeScript 类成员

11

我是 CoffeeScript 的新手(对 JS 也不太熟悉,如果这个问题比较幼稚请见谅),我想创建以下类:

class Test
   a: []

   make: ->
       @a.push ['A', 'B', 'C']

   getdata: ->
       output = ""
       for i in @a
          output += i
       output

b = new Test
b.make()

alert(b.getdata())


c = new Test
c.make()

alert(c.getdata())

我得到的输出是: "A, B, C" "A, B, C, A, B, C"

尽管创建了'Test'的新实例,但数组仍然被添加而未清除。 我在这里做错了什么?我初始化成员变量的方式有问题吗?


3
你应该研究原型如何工作,并查看JavaScript生成的代码。我在Coffeescript中看到很多这样的错误(即使在教程/食谱中也是如此)。我的规则是只在类成员中定义函数和静态属性(我使用@member语法在构造函数中定义实例属性)。虽然Coffeescript使用了class关键字,但确实有点令人困惑。 - Guillaume86
3
旁注:"getdata: -> @a.join('')" 的翻译是:获取数据:-> @a.join('')。 - tokland
感谢Guillaume86和tokland。我从中学到了很多。 - Anoop
有关该主题:在我看来,TypeScript 实现实例成员比 Coffeescript 更合理,您可以在此处尝试:http://www.typescriptlang.org/Playground/ - Guillaume86
1个回答

23

当你定义 a: [] 时,你正在创建一个类原型上的单个数组对象。你创建的每个类实例都会拥有这个相同的数组对象。当一个实例修改了该值时,所有其他实例都可以看到这种变化。

请注意,只有在你修改值时(例如向数组添加项),才会出现这种情况。如果你替换值,例如通过分配一个新数组,那么这只会影响当前实例。

当你想要一个按照每个实例初始化的属性时,应该在 constructor 中定义它,即在实例真正创建时:

class Test
   constructor: ->
       @a = []
       @a.push ['A', 'B', 'C']

   getdata: ->
       output = ""
       for i in @a
          output += i
       output

b = new Test

alert(b.getdata())


c = new Test

alert(c.getdata())

试一下,你会发现它按照你所期望的方式工作。


1
当你看到这样的东西时,难怪人们会感到困惑:http://coffeescriptcookbook.com/chapters/classes_and_objects/chaining - Guillaume86
谢谢!现在我明白了。让我更困惑的是修改/替换行为上的差异。现在这也清楚了。感谢您的帮助。 - Anoop
这个错误的建议在这里也被重复了http://arcturo.github.io/library/coffeescript/03_classes.html,我差点也掉进同样的陷阱。我希望Coffeescript文档能够提供相关建议。 - aaron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接