在Coffee Script中理解类扩展和实例属性
Making sense of class extension and instance properties in Coffee Script
我刚刚进入咖啡脚本和我有问题弄清楚如何类扩展的工作原理。似乎在父类上定义为实例属性的属性在扩展该类时被实现为静态属性。
我有一个叫做Foo的类,我想用它作为两个子类Bar和Goo的基类。我给Foo一个名为foobs的实例属性和一个添加foob的方法,如下所示:
class Foo
foobs:[]
addFoob: (foob) ->
@foobs.push(foob)
我用Bar和Goo扩展Foo,并创建新的实例,如下所示:
class Bar extends Foo
otherMethod: ->
alert 'doing other stuff'
class Goo extends Foo
secondMethod: ->
alert 'doing second stuff'
barInstance = new Bar()
gooInstance = new Goo()
但是当我添加一个Foob到barInstance,它也被添加到gooInstance!
barInstance.addFoob('test')
console.log gooInstance.foobs (outputs ["test"])
显然我在这里做错了什么。我想barInstance和gooInstance各自有自己的"foobs"属性,但出于某种原因,似乎即使foobs是Foo上的实例属性,它被分配为Bar和Goo上的类属性。有什么办法解决这个问题吗?或者可能有我不知道的不同语法?
谢谢
问题在于您如何声明foobs
-您真的希望它在实例上,因此它应该在constructor
函数中声明。目前,它是在所有实例共享的prototype
上声明的。如果我们看看你的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)
将foobs
数组添加到Foo
的每个实例
这是因为您将数组放置在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
数组应该在构造函数中初始化,因为现在所有实例将共享相同的foobs
数组,因为您在prototype
上定义了它。
您可以安全地在prototype
上定义原始值,因为这些值是不可变的,但是您应该避免在prototype
中存储对象,除非您希望这些对象在所有实例中共享。
- ES6构造函数返回基类的实例
- 无法在XUL Firefox扩展中获取TinyMCE的实例
- ES6 类扩展本机类型使实例在某些 JavaScript 引擎中出现意外行为
- 使用lodash'扩展JS对象实例;s的extend方法会导致奇怪的结果
- 在Chrome V8中实例化从Object扩展的类时,super()不传递参数
- 扩展直接实例
- 如何定义扩展方法并将其作为实例和静态方法调用
- 在对象实例化期间扩展 JavaScript 对象
- Firefox浏览器扩展实例
- Chrome扩展:如何管理后台页面的单独实例
- 使用网站的Chrome扩展's加载了jQuery实例
- 如何在NodeJS中使用Backbone扩展模块的新实例
- 我如何重新连接到同一个小行星实例上的Chrome扩展
- 如何创建自定义元素扩展类的新实例
- 在Coffee Script中理解类扩展和实例属性
- 扩展一个函数并对其进行实例化-javascript
- 用原型扩展基实例
- 将主干中现有的模型实例扩展/强制转换为派生模型的实例(类似于java中的强制转换)
- 只允许一个Chrome js扩展的活动实例
- 适当地扩展数组,保持子类的实例