2

一体何がここで起こっているのですか?-classにで設定されたデータを含めるには
どうすればよいですか?また、兄弟クラスに設定されたデータが相互に干渉しないようにするにはどうすればよいですか?DaughterBrother

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' }
4

2 に答える 2

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初期化されますが、一方、インスタンスが作成されるたびに、コンストラクターで初期化され、新しい空のオブジェクトが割り当てられます。

于 2012-10-15T13:13:16.127 に答える
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サイドバイサイドウィンドウにリンク機能があることに気づきました。サイドバイサイドコードへのリンクは次のとおりです。

更新#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)を親レベルに保持し、コンストラクターを介して設定し、親関数を介してアクセスします。

于 2012-10-15T12:56:02.273 に答える