Coffeescript中的类和继承

时间:2012-10-15 12:49:09

标签: javascript oop coffeescript

这里到底发生了什么? Daughter - 类如何包含在Brother中设置的数据,以及如何确保兄弟类中的数据集不会相互干扰?

class Parent 
  data: {}

class Child extends Parent
  age: 10

Son = new Child
Son.data.name = "John Doe"

Daughter = new Child
console.log Daughter.data # => { name: 'John Doe' }

2 个答案:

答案 0 :(得分:2)

问题似乎是,您没有使用构造函数为每个实例初始化data。相反,你给它一个恰好位于Animal的初始值是可变的。无论何时分配给instance.data.attribute,您实际上都在修改该共享对象。如果您使用了data: 1,则不会看到此共享行为。

这可以解决您的问题:

class Parent 
  constructor: () ->
    @data = {}

免责声明:我不是很精通JavaScript的原型继承,所以我提供的技术细节可能不正确,但对这种现象的描述似乎是准确的。

编译时的差异

class Parent 
  staticD: {}
  constructor: ->
    @data = {}

编译为:

Parent = (function() {

  Parent.prototype.staticD = {};

  function Parent() {
    this.data = {};
  }

  return Parent;

})();

正如您所看到的,staticD仅在创建“类”时被初始化,另一方面,data在构造函数中初始化,并在每次实例时分配一个新的空对象已创建。

答案 1 :(得分:1)

如果您使用CS代码并将其放在CoffeeScript网站(http://coffeescript.org/)上的并排编辑器中,您会看到data在原型上Parent“班级”。可以认为该原型是您创建的新功能(类)的模板。该原型要么包含其他函数,要么包含可用于所有实例的变量(如OO静态变量)。

您要将name添加到“静态”变量data。然后,它将可用于从Parent“派生”的所有实例。

我不确定那里发生的内部运作,但是来自OO世界,这就是我如何解释它。我希望这会有所帮助。

通过COFFEESCRIPT网站生成的代码

var Child, Daughter, Parent, Son,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Parent = (function() {

  function Parent() {}

  Parent.prototype.data = {};

  return Parent;

})();

Child = (function(_super) {

  __extends(Child, _super);

  function Child() {
    return Child.__super__.constructor.apply(this, arguments);
  }

  Child.prototype.age = 10;

  return Child;

})(Parent);

Son = new Child;

Son.data.name = "John Doe";

Daughter = new Child;

alert(Daughter.data.name);

<强>更新 刚注意到CS并排窗口有一个链接功能。这是并排代码的link

更新#2

在评论中回答你的问题,我不确定你想做什么,但你可以这样做:

class Parent 
  #data: {}

class Child extends Parent
  constructor: (@name) ->
  age: 10
  sayHi: -> alert "Hi " + @name


Son = new Child "John Doe"

Daughter = new Child "Sarah Jane"

Son.sayHi()
Daughter.sayHi()

也许将name变量(或整个data变量)保留在父级别,并通过构造函数设置它并通过父函数访问它。