javascriptでエミュレートされた多重継承は悪夢になります。
動的な多重継承を可能にするためにカスタムクラスラッパー全体を作成しましたが、それだけの価値がないため、1か月後に放棄しました。複雑さは手に負えないほど大きくなります。
多重継承を使用するのではなく、親メソッドを使用してオブジェクトを拡張できます。
外部の「クラシックOO」エミュレーターを含めるのではなく、単純なオブジェクトコンストラクターとプロトタイプに固執することをお勧めします。JavaScriptは、別のクラスを拡張するクラスではなく、別のオブジェクトから継承するオブジェクトである典型的なOOに重点を置いています。
多重継承が必要な場合は、オブジェクトコンポジションに固執します。
警告:これは_
単純さと簡潔さのために使用されます。
function Child() {
var parent1 = new Parent1();
var parent2 = new Parent2();
// bind this to parent1 so it's got it's own internal scope
_.bindAll(parent1);
_.bindAll(parent2);
// extend this with parent1 and parent2
_.extend(this, parent1);
_.extend(this, parent2);
}
はい、あなたはinstanceof
チェックを失います。それに対処します。
より一般的には、任意のオブジェクトを拡張できます。
function extend(f, arr) {
// return a new function to replace f.
return function() {
// store the correct this value
var that = this;
// call original f
f.apply(this, arguments);
// for each parent call it with the original this
_.each(arr, function(v) {
v.apply(that, arguments);
});
// add f to the parent array
arr.push(f);
// store the array on the object to use with instance_of
this.__instance = arr;
}
}
function instance_of(o, klass) {
// is the klass included in the .__instance array ?
return _.include(o.__instance, klass);
}
function Child() {
// do stuff
this.method = function() { console.log("method"); return this;};
}
function Parent1() {
this.foo = function() { console.log("foo"); return this; };
}
function Parent2() {
this.bar = function() { console.log("bar"); return this;};
}
Child = extend(Child, [Parent1, Parent2]);
var c = new Child();
console.log(instance_of(c, Parent1)); // true
console.dir(c);
c.method().foo().bar();
underscore.js
これは、サンプルコードを小さく保つために、いくつかの優れた抽象化を実装することに依存しています。.extend、.bindAll。
実例を見る