6

_data作成されたすべてのオブジェクトの定義として、プロパティをプロトタイプに保存しました。

 function A() {}
 A.prototype._data = [];

から作成されたすべてのオブジェクトには、Aプロパティがあります_data

プロトタイプがプロトタイプ チェーン内のすべてのプロトタイプからの値_dataを持つプロトタイプの継承が必要です。_data

直接的な方法はわかりません。この例では getter を使用していget()ます。

 function A() {}

 A.prototype._data = [];

 A.prototype.add = function(rec) {
   this.__proto__._data.push(rec);
 }

 A.prototype.get = function() {
   if(typeof this.__proto__.constructor.prototype.get == 'function')
   {
     return this.__proto__.constructor.prototype.get().concat(this.__proto__._data);
   }
   else
   {
     return this.__proto__._data || [];
   }
 }

 function B() {}
 B.prototype = Object.create(A.prototype, { constructor: { value: B }});
 B.prototype._data = [];

値を持つオブジェクトと値を持つaオブジェクトを作成すると、が返されます。そして後でプロトタイプが で拡張される場合、関数は を返します。aabbbb.get()[aa, bb]_dataAaaaab.get()[aa, aaaa, bb]

 var a = new A(), b = new B();

 a.add('aa');
 b.add('bb');
 console.log(b.get()); // [aa, bb]

 a.add('aaaa');
 console.log(b.get()); // [aa, aaaa, bb]

 // EDITED - _data in A prototype shoud be without B
 console.log(a.get()); // [aa, aaaa]

これを達成するための良い(標準的な)方法はありますか?コンストラクターの修正を使用しObject.create、親プロトタイプをconstructor.prototype?で参照することを意味します。

ここにデモがあります:http://jsfiddle.net/j9fKP/

このすべての理由は、スキームの継承が許可されている ORM ライブラリのスキームのフィールド定義にあります。子スキームには、親スキームのすべてのフィールドが必要です。

4

3 に答える 3

1
 function A() {}
     A.prototype._data = [];

 A.prototype.add = function(rec) {
   this._data.push(rec);
 }

 A.prototype.get = function() {
   return this._data;
 }

 function B() {}
 B.prototype = Object.create(A.prototype, { constructor: { value: B    }});

 B.prototype._data = [];

 B.prototype.get = function() {
   return A.prototype._data.concat(this._data);
 }  

 a.add('aa');
 b.add('bb');
 console.log(b.get()); // [aa, bb]

 a.add('aaaa');
 console.log(b.get()); // [aa, aaaa, bb]

フィドル

于 2013-03-16T14:08:00.017 に答える
1

プロトタイプがプロトタイプ チェーン内のすべてのプロトタイプからの値_dataを持つプロトタイプの継承が必要です。_data

それは別のことです。「プロトタイプの継承」とは_data、現在のオブジェクトにプロパティがある場合、チェーン内をそれ以上検索しないことを意味します。また、ネストされたオブジェクトの一種の問題のようですが、本当に何を望んでいるのかわかりません。ただし、実際にそれらを連結したい場合は、配列オブジェクトを別の配列から継承させることはほとんど意味がありません。

だからあなたのゲッターは本当にいいと思います。

これを達成するための良い(標準的な)方法はありますか?Object.create 中にコンストラクター修正を使用し、constructor.prototype で親プロトタイプを参照することを意味します。

コンストラクターの修正は便利ですが、実際にはまったく役に立ちません (特に、 standard-conform が必要な場合Object.create)。

ただし、this.__proto__.constructor.prototypeまたは.__proto__.constructor.prototype冗長です。どちらも非標準であるか、コンストラクターの修正が必要なため、標準関数を使用しObject.getPrototypeOf()プロトタイプオブジェクトを取得する必要があります。

次の非常に一般的なソリューションを使用すると、継承 (A.proto、B-proto、B-instance など) を任意の深さにネストできます。から継承するものはすべてA.prototype、現在のオブジェクトにadd追加するメソッドと、プロトタイプ チェーンをトラバースしてすべてを収集するメソッドを持ちます。_dataget_data

function A() {
    // this._data = []; // why not?
}
A.prototype._data = []; // not even explicitly needed
A.prototype.add = function(rec) {
    if (! this.hasOwnProperty("_data")) // add it to _this_ object
        this._data = [];
    this._data.push(rec);
}
A.prototype.addToAllInstances = function(rec) {
    Object.getPrototypeOf(this).add(rec);
}
A.prototype.get = function() {
    var proto = Object.getPrototypeOf(this);
    var base = typeof proto.get == 'function' ? proto.get() : [];
    // maybe better:
    // var base = typeof proto.get == 'function' && Array.isArray(base = proto.get()) ? base : [];
    if (this.hasOwnProperty("_data"))
        return base.concat(this._data); // always get a copy
    else
        return base;
}

function B() {
    A.call(this);
}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});
B.prototype._data = []; // not even explicitly needed

使用例:

var a = new A();
var b = new B();

a.add('ai');
a.get(); // [ai]

a.addToAllInstances('ap'); // === A.prototype.add('ap');
a.get(); // [ap, ai]
new A().get(); // [ap]
b.get(); // [ap]
b.prototype.get(); // [ap]

b.add('bi');
b.get(); // [ap, bi]

a.addToAllInstances('aap');
b.addToAllInstances('bp');
b.get(); // [ap, aap, bp, bi]
于 2013-03-16T13:57:08.757 に答える
1

あなたが今何をしたいのかをよりよく理解していると思うので、以前の回答を削除して、これを投稿しています。

これが私がそれを行う方法だと思います(さらによく理解しても、まったく異なるアプローチが良くないということはまったく確信が持てないという警告があります):

function A() {}
A.prototype._Adata = [];

A.prototype.add = function(rec) {
  this._Adata.push(rec);
};

A.prototype.get = function() {
  return this._Adata;
};

function B() {}
B.prototype = Object.create(A.prototype, { constructor: { value: B }});

B.prototype._Bdata = [];

B.prototype.add = function(rec) {
  this._Bdata.push(rec);
};
B.prototype.get = function() {
  return this._Adata.concat(this._Bdata);
  // Or: return A.prototype.get.call(this).concat(this._Bdata);
};

var a = new A();
var b = new B();

a.add('aa');
b.add('bb');
console.log(b.get()); // [aa, bb]

a.add('aaaa');
console.log(b.get()); // [aa, aaaa, bb]

フィドル

そうすれば、の内部Bに深く入り込むことはありません。A

于 2013-03-16T14:17:12.870 に答える