Coffeescript:声明一个类的成员变量是危险的?

时间:2015-02-16 15:37:05

标签: inheritance coffeescript

有一个coffeescript类,如:

class A
  headers: []

  addHeader: (name, value) ->
    @headers.push {
      name: name,
      value: value
    }


a = new A()
a.addHeader 'header1', 'value1'
console.log 'A:', a.headers
console.log '---'
b = new A()
b.addHeader 'header2', 'value2'
console.log 'B:', b.headers
console.log '---'
console.log 'A:', a.headers

执行此脚本会给我以下输出:

A: [ { name: 'header1', value: 'value1' } ]
---
B: [ { name: 'header1', value: 'value1' },
  { name: 'header2', value: 'value2' } ]
---
A: [ { name: 'header1', value: 'value1' },
  { name: 'header2', value: 'value2' } ]

为什么要将元组{'header2': 'value2'}添加到第一个对象A中呢?

这是一个小提琴:http://jsfiddle.net/L5c1nv3z/

我一定是做错了。虽然我更喜欢为类声明成员变量,以便跟踪它们。

1 个答案:

答案 0 :(得分:2)

那是因为你的课程将编译为:

var A;

A = (function() {
  function A() {}

  A.prototype.headers = [];

  A.prototype.addHeader = function(name, value) {
    return this.headers.push({
      name: name,
      value: value
    });
  };

  return A;

})();

如您所见,headers是A.prototype的属性。由于您没有为A class的每个实例覆盖它,因此在您的示例中创建了ab),在this.headers.push方法中调用addHeader时它总是修改同一个数组 - 属于A.prototype的数组。

headers使用A class功能的每个实例创建唯一的constructor数组。尝试这样做:

class A
  constructor: ->
    @headers = []

  addHeader: (name, value) ->
    @headers.push {
      name: name,
      value: value
    }

您可以在The Little Book on CoffeeScript中了解更多相关信息。