1

編集:動作を示すために私の例を修正しました。

detailsAbstractParentのプロパティを「インスタンスプロパティ」と呼ぶものにしたかったのですが、それは「静的プロパティ」のように機能します。これらの用語はjavascriptには適切ではないことに気付いたので、新しい子クラスを作成するときに、独自のAbstractParentプロトタイプを取得しないのはなぜですか?なぜ彼らは同じものを共有するのですか?

以下のコードでは、空のアラートを期待していますが、代わりに「新しい詳細」を取得します

var AbstractParent = Backbone.Model.extend({
  details: [],

  addDetail: function(detail) {
    this.details.push(detail);
  },

  getDetails: function() {
    var rtn = '';
    for(var i=0;i<this.details.length;i++) {
      rtn += this.details[i];
    }
    return rtn;
  }
});

var Child = AbstractParent.extend({});

var ch1 = new Child;
ch1.addDetail("new details");
var ch2 = new Child;

alert(ch2.getDetails()); // => 'new details'

detailsこれは、が配列の場合にのみこのように機能するようです。文字列またはオブジェクトの場合、およびによって共有されませch1ch2

4

3 に答える 3

2

さて、私は問題を理解しました。私の最初の質問のコードは正確ではなかったので、他の回答者に謝罪します (私が提示したコードのコンテキストでは彼らは正しかったです)。

解決策は次のとおりです: 配列としてプロトタイプ化された Javascript オブジェクト メンバーは、すべてのクラス インスタンスによって共有されます。

基本的に、両方の Child インスタンスがプロトタイプとして同じ AbstractParent 関数を共有しているという事実は、AbstractParent で何かを変更すると、両方の子のプロトタイプに反映されることを意味します。

The reason this only manifests itself when using an array is because I initialized the array in the prototype and then just alter it rather than overwriting it in the addDetail function. When I used objects or strings for the property names and then did an assignment, the this in the context at the time of the function call belongs to the Child instance, so doing this.name = 'Billy'; in an AbstractParent function is in fact attaching that to the Child instance instead, and not in the AbstractParent. I was thinking each Child instance would get its own AbstractParent prototype instance and that when I accessed this.name it wouldn't find it on the Child and would go to this.prototype.name instead.

私の質問のコードではinitialize、詳細配列をインスタンス化する関数を AbstractParent に追加することでこれを修正できます。しかし、子に関数を追加し、initializeその中で親コンストラクターを呼び出さなかった場合、以前と同じ問題が発生します。

于 2011-05-27T16:03:14.707 に答える
1

名前プロパティ(またはオブジェクト)をベースAbstractParentに割り当て、このベースから拡張する2つのオブジェクトを定義しました。そのため、それぞれが独立してこの名前オブジェクトを持ちますが、デフォルトではベースで割り当てられた値になります。

コードでは、ch1.nameを「Billy」に割り当てていますが、ch2のnameの値を変更するために何もしていません。あなたのコード例は実際には間違っていると私は主張します。アラートによって表示される値は「デフォルト名」である必要があります。

ブラウザにbackbone.jsをロードしてから、デバッガコンソールに移動し、上記のステートメントをもう一度入力できますか?そうすれば、あなたが期待する振る舞いを見つけることができると思います。

于 2011-05-27T01:33:31.827 に答える
1

ch1.nameを変えるとch2.nameも変わるということですか?正確なコードを実行しましたが、その結果は得られませんでした。ch2.name は「デフォルト名」のままでした。

name プロパティを探すとき、ブラウザは ch1.name = "Billy" を設定した後、次のルートを取りました...

ch1

  • inherits.child (ch1 インスタンス)

    • 名前:「ビリー」

ch2

  • inherits.child (ch2 インスタンス)
    • __proto__ (SecondChild プロトタイプ)
      • __proto__ (AbstractParent プロトタイプ)
        • 名前:「デフォルト名」

デバッグ コンソール (Firefox の Firebug または Chrome の Developer Tools / Javascript コンソール) を開きます。

于 2011-05-27T01:43:27.833 に答える