Javascript 在Coffee脚本中理解类扩展和实例属性
我刚刚开始学习咖啡脚本,在理解类扩展如何工作时遇到了一些问题。在父类上定义为实例属性的属性似乎在扩展该类时被实现为静态属性 我有一个名为Foo的类,我想用它作为两个子类Bar和Goo的基类。我为Foo提供了一个名为foobs的实例属性和一个添加foob的方法,如下所示:Javascript 在Coffee脚本中理解类扩展和实例属性,javascript,oop,coffeescript,Javascript,Oop,Coffeescript,我刚刚开始学习咖啡脚本,在理解类扩展如何工作时遇到了一些问题。在父类上定义为实例属性的属性似乎在扩展该类时被实现为静态属性 我有一个名为Foo的类,我想用它作为两个子类Bar和Goo的基类。我为Foo提供了一个名为foobs的实例属性和一个添加foob的方法,如下所示: class-Foo foobs:[] addFoob:(foob)-> @foobs.push(foob) 我用Bar和Goo扩展了Foo,并创建了新的实例,如下所示: 类栏扩展了Foo 其他方法:-> 提醒“做其他事情”
class-Foo
foobs:[]
addFoob:(foob)->
@foobs.push(foob)
我用Bar和Goo扩展了Foo,并创建了新的实例,如下所示:
类栏扩展了Foo
其他方法:->
提醒“做其他事情”
类Goo扩展了Foo
第二种方法:->
提醒“正在做第二件事”
barInstance=新杆()
gooInstance=新的Goo()
但当我向barInstance添加一个Foob时,它也会添加到gooInstance
barInstance.addFoob('test'))
console.log goodinstance.foobs(输出[“测试”])
很明显我做错了什么。我希望barInstance和gooInstance都有自己的“foobs”属性,但出于某种原因,似乎即使foobs是Foo上的实例属性,它也被指定为Bar和Goo上的类属性。有什么办法可以解决这个问题吗?或者我不知道有不同的语法
谢谢应该在构造函数中初始化
foobs
数组,因为现在所有实例都将共享相同的foobs
数组,因为您在原型上定义了它
您可以在原型
上安全地定义基元值,因为这些值是不可变的,但是您应该避免在原型
中存储对象,除非您希望这些对象在所有实例中共享。这是因为您将数组放置在Foo
原型上,因此,它将在所有实例中共享。相反,您需要为Foo
的每个实例创建一个数组,并直接添加它
class Foo
foobs:null, # This isn't needed, but it's good for documentation.
constructor: ->
@foobs = []
addFoob: (foob) ->
@foobs.push(foob)
从不同的角度来看,你所拥有的基本上是:
sharedFoobs = []
class Foo
foobs: sharedFoobs
这就更清楚地表明,永远不会创建新数组。问题在于如何声明foobs
-您确实希望它位于实例上,因此应该在构造函数中声明它。目前,它在所有实例共享的原型上声明。如果我们查看您的Foo
声明编译为什么,我们可以看到这种情况:
class Foo
foobs:[]
addFoob: (foob) ->
@foobs.push(foob)
汇编至:
var Foo = (function() {
function Foo() {}
Foo.prototype.foobs = [];
Foo.prototype.addFoob = function(foob) {
return this.foobs.push(foob);
};
return Foo;
})();
您要做的是声明一个构造函数,如下所示:
class Foo
constructor: (@foobs = [])->
addFoob: (foob) ->
@foobs.push(foob)
这将在Foo
的每个实例中添加一个foobs
数组谢谢您的回答!之所以接受这一点,是因为方法参数(@foobs=[])的内联语法很酷,而我一直对无法在JavaScript中实现这一点感到恼火。如果可以的话,我也会投票支持这一点。感谢您对原型上对象的解释。