Coffeescript:声明 class 的成员变量危险吗?

Coffeescript: Declaring member variables of a class dangerous?

有一个 coffeescript class 喜欢:

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 也是如此?

这里是 fiddle:http://jsfiddle.net/L5c1nv3z/

一定是我做错了。尽管我更喜欢为 classes 声明成员变量以便跟踪它们。

那是因为您的 class 将编译为:

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.pushaddHeader 方法中调用时它总是修改同一个数组 - 属于 A.prototype.

的数组

要为 A class 的每个实例创建唯一的 headers 数组,请使用 constructor 函数。尝试这样做:

class A
  constructor: ->
    @headers = []

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

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