7

PrototypicalInheritanceを使用するJavaScriptプロジェクトに取り組んでいます。私がそれを使用することに決めた方法は次のとおりです。

var MySuperClass = function (param) {
    this.prop = param;
};
MySuperClass.prototype.myFunc = function () {
    console.log(this.prop);
};

var MySubClass = function (param) {
    MySuperClass.call(this, param);
};
MySubClass.prototype = new MySuperClass();
MySubClass.prototype.constructor = MySubClass;

var obj = new MySubClass('value');
obj.myFunc();

継承に重点を置いて。

MySubClass.prototype = new MySuperClass();これに関する問題は、各クラス(スーパーとサブ)のコンストラクターにconsole.logを配置すると、スーパークラスが2回呼び出されることです。1回はパラメーターなしでサブクラスに渡され、もう1回はパラメーター付きです。サブクラスのコンストラクターで「コンストラクターが盗まれた」場合。

これらのパラメーターを保存しようとすると、エラーが発生する可能性があります(つまり、空のパラメーターを処理するためのロジックを追加する必要があります)。

今私がこれを行う場合:

var MySubClass = function (param) {
    MySuperClass.call(this, param);
};
MySubClass.prototype = MySuperClass;
MySubClass.prototype.constructor = MySubClass;

すべてが正しく機能しているように見えますが、(私のグーグルで)これを行う人を見たことがありません。

誰かが私に2番目のものが間違っているかどうかとその方法(Crockford継承関数に似ているようです)と、1番目のものが2回発火しないように修正する方法を説明できますか?

4

1 に答える 1

8

これを行うことは正しい解決策ではありません:

MySubClass.prototype = MySuperClass;

関数自体をプロトタイプ オブジェクトではなくプロトタイプとして設定しているため、期待どおりに継承されません。


しかし、あなたは正しいです。これを行うと、コンストラクターが呼び出され、問題が発生する可能性があります。

MySubClass.prototype = new MySuperClass();

Object.create解決策は、継承を設定するために使用することです。提供されたオブジェクトから継承する新しいオブジェクトを提供しますが、コンストラクターは呼び出しません。

MySubClass.prototype = Object.create(MySuperClass.prototype);

MySubClass.prototypeこれで、から継承したに割り当てられたオブジェクトMySuperClass.prototypeができましたが、実際にコンストラクターを呼び出す必要はありませんでした。


非 ES5 準拠の実装は をサポートObject.createしませんが、(部分的な) shim を作成できます。

if (!Object.create) {
    Object.create = function(proto) {
        function F(){}
        F.prototype = proto;
        return new F();
    };
}

繰り返しますが、これは完全な shim ではありませんが、プロトタイプ オブジェクトを参照するコンストラクターを呼び出さなくても、継承されたオブジェクトを作成できる程度にエミュレートします。

于 2012-11-02T16:06:10.233 に答える