Inheritance Coffeescript:声明类的成员变量危险吗?
拥有一个coffeescript类,如:Inheritance Coffeescript:声明类的成员变量危险吗?,inheritance,coffeescript,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.addH
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
这是一把小提琴:
我一定做错了。尽管我更喜欢为类声明成员变量,以便跟踪它们。这是因为您的类将编译为:
var-A;
A=(函数(){
函数A(){}
A.prototype.headers=[];
A.prototype.addHeader=函数(名称、值){
返回此.headers.push({
姓名:姓名,,
价值:价值
});
};
返回A;
})();
如您所见,标题
是原型的属性。由于您没有为您创建的A类的每个实例重写它(A
和b
),因此当this.headers.push在addHeader
方法中调用时,它总是修改相同的数组-属于A.prototype
的数组
要为类的每个实例创建唯一的头
数组,请使用构造函数
函数。试着这样做:
A类
构造函数:->
@标题=[]
addHeader:(名称、值)->
@1.push{
姓名:姓名,,
价值:价值
}
您可以在中了解更多信息。这不是真正的CoffeeScript问题,顺便说一句,这是JavaScript中原型工作方式的副作用。不要将可变属性附加到原型,因为原型属于所有人。OTOH,如果您明确希望共享可变属性,请将其附加到原型上,然后您需要一条注释来解释其用途,否则人们可能会认为这是一个bug。谢谢。因此,我应该始终在构造函数中分配成员变量?或者什么是“最佳实践”?答案当然是“视情况而定”。不可变的东西(字符串、数字、布尔值)在原型中很好,因为不指定新值就无法更改它们,也不会干扰原型。在内部化原型系统的工作方式之前,使用构造函数可能更安全、更一致。