2

this code

class Foo
  bar: []

test = new Foo()
test.bar.push('b')

test2 = new Foo()
console.log test2.bar

Will produce output ['b']. How it is even possible?

Edit:

This is what CoffeScript generates:

// Generated by CoffeeScript 1.4.0
var Test, test, test2;

Test = (function() {
  function Test() {}
  Test.prototype.a = [];
  return Test;
})();

test = new Test();
test.a.push('b');

test2 = new Test();
console.log(test2.a);

And therefore is exactly true what is written below. Thank you guys.

Jakub Truneček
  • 8,800
  • 3
  • 20
  • 35

2 Answers2

3

bar is a single array instance that belongs to Foo.prototype.
new Foo().bar will always refer to this same array instance.

Therefore, any mutations performed through one Foo instance will also be visible thtough any other Foo instance.

The solution:

Never put mutable state in a prototype.

Community
  • 1
  • 1
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • "Never put mutable state in a prototype." - rightfully bolded. I got bitten by that when I was less experienced. :) – Myrne Stol Jun 07 '13 at 16:40
0

If you want Foo's to be created with this.bar = [], do it in the constructor:

class Foo
  constructor: -> @bar = []
Andbdrew
  • 11,788
  • 4
  • 33
  • 37
  • Yeah, this is how I am doing it now. My fault. CoffeeScript confused me - in the moment I saw generated code, it was clear to me. Thank you. – Jakub Truneček Jun 07 '13 at 14:25