2009-09-28 9 views
8

私はPrototype/jQueryを使わずにJavaScriptでオブジェクト指向のプログラミングをしています(私は他のもののためにjQueryを使用しています)。これまではうまくいきましたが、私は継承に関する問題に遭遇しました。基本的に、コンストラクタでオブジェクトを宣言すると、インスタンス間でオブジェクトが共有されます。以下にいくつかのサンプルコードである:Javascriptの継承 - コンストラクタで宣言されたオブジェクトはインスタンス間で共有されますか?

A = function() 
    { 
     this.y = new Array(); 
    } 

    A.prototype.doStuff = function(n) 
    { 
     this.y.push(n); 
    } 

    B = function() 
    { 
    } 

    B.prototype = new A(); 

    var b1 = new B(); 
    var b2 = new B(); 

    b1.doStuff(100); 
    b2.doStuff(200); 

    console.log("b1:"); 
    console.log(b1); 
    console.log("b2:"); 
    console.log(b2); 

これはb1b2両方の配列[100, 200]を出力します。私が欲しいのは、b1b2yのための独自の別の配列を持つことです。これについてどうすればいいですか?

(PSは。私はしかし、私はむしろ、そのクラスのシステムを使用するように私のコードの束を書き換えないでしょう。プロトタイプのクラスシステムは、このためで構築された何かを持っていると仮定)

答えて

7

Aコンストラクタ関数は、すべてのBインスタンスに対して1回だけ実行されるため、this.yは1つの配列への参照になります。 Bからの参照はプロトタイプチェインを介して単一の中央A参照(これはただ1つのy)に解決されます。これは非常に便利な機能です。あなたがここでやろうとしていることではありません。

答えは、構成を初期化から分離することです。コンストラクタは中央リソースを設定し、イニシャライザはインスタンスを初期化します。 JavaScriptで見た "クラス"実装のほとんどがこの問題をどのように処理するかです。それが機能するには、階層内の各レベルが前のレベルのイニシャライザ(他のメソッドにも便利です)(例:スーパーコール)を呼び出す手段を提供する必要があります。あなたはこのためにプロトタイプのようなものを使用して、おそらく方がいいでしょう、なぜ

Supercallsは以下のとおりです。彼らはよくやるのは難しいですし、それが「孫」の問題に陥り非常に簡単です - 動作しているようですソリューションしかし、親との作業のみが終了する< - 親構造ではなく、 - ビルド< - グランドチャイルド構造。

しかし、あなた自身の継承メカニズムを実行しようとしている場合は、私の哀れな貧血のブログのthis post on supercallsが役に立つかもしれません。 Prototypeの継承メカニズムの簡略化されたバージョンを取り、それを少し解体して、Prototypeの現在のスーパーコールでいくつか問題がないスーパーコールを行う方法について話します。それはあなた自身の仕組みであなたを助けるかもしれません。

+1

はい - 私はあなたのブログ記事に書いたようなことをやりました。基本的に、 'target 'のインスタンス固有の変数を初期化する別の' construct(target) '関数があります。子供たちはスーパークラスでこれを呼びます。特にかわいいですが、うまくいくようです。 –

2
B.prototype = new A(); 

これはのインスタンスを1つだけ作成されますあなたは

B = function() 
{ 
    this.$super = new A(); 
} 


B.prototype.doStuff = function() 
{ 
    return this.$super(args); 
} 


C = function() 
{ 
    this.$super = new B(); 
} 


C.prototype.doStuff = function() 
{ 
    return this.$super(args); 
} 

C.prototype.whoIsMyGrandParent = function() 
{ 
    return this.$super.$super; 
} 

JavaScriptのようなSTHを行うことを検討する可能性があるすべてのB.

のための本当のinheritationを持っていません

+0

私は「孫」という問題に悩まされています。「B」から派生した 'C 'があるとすぐに、' B'がそれを参照する方法がないので、 A'。 (また、FWIW、 'super'はJavaScriptの予約語です。) –

+0

申し訳ありません。スクリプトで$ superを使用しました。 私はあなたの孫問題を見ません。 – jantimon

+1

Javascriptに継承があります。古典的な継承ではありません。 Prototype OOは全く異なるが、完全に正当なOOの形式である。 – eyelidlessness

関連する問題