1

タイトルは少し漠然としていますが、正直なところ、この問題の解決策を理解していないと、それ以上にうまく定義することはできません。

状況

私は、javascript のプロトタイプと継承に頭を悩ませようとしています。ユース ケースは、単一のベース タイプ「A」です。そして単一のサブタイプ「B」。この問題を示す最も単純なコードの例を次に示します。動作中のバージョンはここで見ることができます。

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
    function A () {
        this.node = document.createElement('div');
        this.node.innerHTML = 'A';
    }

    A.prototype.show = function () {
        document.body.appendChild(this.node);
    }

    function B () {
        this.node.innerHTML = 'B';
    }

    B.prototype = new A();
    B.prototype.constructor = B;

    function make_a () {
        (new A()).show();
    }

    function make_b () {
        (new B()).show();
    }
  </script>
 </head>
 <body>
  <button onclick="make_a()">Make A</button>
  <button onclick="make_b()">Make B</button>
 </body>
</html>

問題

  • 最初のボタンをクリックすると、期待どおりの動作が得られます。クリックするたびに「A」の新しいインスタンスが作成され、DOM に追加されます。
  • ただし、2 番目のボタンで同じことを行うと、'B' のインスタンスが 1 つだけ DOM に追加され、そのままになります。何回クリックしても構いません。
  • この後で「A」をクリックすると、期待どおりに新しい「A」が再び作成されます。
  • 2 番目のボタンをもう一度クリックすると、既存の「B」ノードがノード リストの最後の場所に移動します。

make_b()がと同じように動作しないのはなぜmake_a()ですか?

いくつかのメモ:

テスト中のブラウザは Chromium 20 以降と Firefox 13 以降です。

4

2 に答える 2

1

説明のために:

変更時

A.prototype.show = function () {
    document.body.appendChild(this.node);
    document.body.appendChild(this.node);
}

同じノード パラメータで appendChild を複数回呼び出しても、複数の appendend 子が発生しないことがわかります。

修正時

function B () {
    this.node.innerHTML = Math.random() > 0.5 ? "B":"C";
}

関数 B が (A によって) 最後に挿入された子をオーバーライドすることがわかります。(B() 自体は div を作成しません)。

関数 A() は、命令 B.prototype = new A(); によってページの読み込み時に呼び出されます。ボタンAを押すたびに。そのため、ボタン B がアクティブになる前に、常に最新の div 子が作成されます。この最後に作成された div は、show() が呼び出されるたびに、つまりボタンのクリックに反応してドキュメントに追加されます。

関数 B() は新しい div ノードを作成しないため、B() は A() によって作成/追加された最新の子ノードを使用して「B」を挿入します。

于 2012-07-22T17:20:17.797 に答える
1

Aコンストラクター内からコンストラクターを呼び出す必要がありますB

function B () {
    A.call(this);
    this.node.innerHTML = 'B';
}

これがフィドルです:http://jsfiddle.net/QUnDK/

于 2012-07-22T16:27:29.957 に答える