0

JavaScriptでのオブジェクト指向プログラミングについてMikeKossを読みました。彼はサブクラス化について簡単に話し、「代替のサブクラス化パラダイム」に触れています。この例の後、Kossは次のように書いています...

instanceof 残念ながら、この手法では、演算子を使用してスーパークラスのメンバーシップをテストすることはできません。ただし、複数のスーパークラス(多重継承)から派生できるという追加の利点があります。

...そしてそれは私に考えさせました。多重継承のアイデアはかっこいいようです!したがって、2つの質問があります。

  1. 多重継承のアイデアは実用的ですか?それは実際に実践されていますか?長所または短所はありますか?
  2. instanceof演算子をオーバーライドして、その機能を多重継承に拡張するにはどうすればよいですか?
4

2 に答える 2

2

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

実例を見る

于 2011-03-31T18:12:46.787 に答える
1

John Resigのクラス構造や他の多くのクラス構造では、instanceofチェックが可能です。

あなたはinstanceofをオーバーライドすることについて考えることに夢中ではありません(私は実際にあなたにその考えを賞賛します、それは私がすることです:))、しかしそれは不可能です。instanceofは関数ではなく、コンパイラによって解析されるjavascriptキーワードであるため、オーバーライドできません。

多重継承に関しては、追跡することが不可能であるため、実際には誰もそれを使用しません。2つの親クラスが同じことを実装するとどうなりますか?どちらが優先されますか?それらを子クラスとどのように区別しますか?

于 2011-03-31T17:50:13.463 に答える