4

Boy.prototype = new Human;誰もが継承をシミュレートするために使用している理由がわかりません。ほら、私たちが欲しいのはAの関数ですよね?新しいAをインスタンス化せずにそれを行うことができます(実際、新しいAをインスタンス化すると、実際にインスタンス化関数を実行しているという意味で、望ましくない結果が得られます)。

それで、これはより良い解決策ではありませんか?

for (var prop_name in Human.prototype) {
Object.defineProperty(
          Boy.prototype,
          prop_name,
          Object.getOwnPropertyDescriptor(Human.prototype,prop_name)
        );
}

私たちがその特定であり、Human.prototypeの列挙可能なプロパティだけでなくObject.getOwnPropertyNames、プロトタイプチェーンでそれを使用して呼び出すことでそれを実現できることを望んでいるとしましょう。これは、を通じて利用できますObject.getPrototypeOf

Boy.prototype = new Human;では、より良いオプションを利用できる場合に、継承をシミュレートすることの利点は正確には何でしょうか。

4

2 に答える 2

4
  • プロトタイプチェーンを正しく設定します。つまり、instanceof機能しisPrototypeOf()ます。
  • 冗長ではありません

プロトタイプオブジェクトを作成するためだけにコンストラクター関数を使用しているときに、コンストラクター関数が通常の初期化を実行しないようにするための、単純ですが醜い回避策があります。たとえば、次のいずれかの引数を確認できます。

function Boy(name) {
    if (arguments.length == 1) {
        this.name = name;
        // Do other initialization
    }
}

...または、初期化を明示的に呼び出す必要のある別のメソッドに移動します。

function Boy(name) {}

Boy.prototype.init = function(name) {
    this.name = name;
    // Do other initialization
}

init()これには、新しいを作成するたびに呼び出すことを忘れないようにする必要があるという明らかな欠点がありますBoy

ECMAScript 5環境(たとえば、ほとんどのブラウザーの現在のバージョン)では、ECMAScript 5の方が適している場合がありますObject.create()。これにより、別のオブジェクトから直接継承するオブジェクトを作成し、プロトタイプチェーンを設定できます。これは、ES5以外の環境でエミュレートできます(ただし、おおよその場合:ES5のObject.definePropertyを参照してください)。

if (!Object.create) {
    Object.create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }; 
}
于 2011-05-13T11:34:49.703 に答える
4

より良いオプションは、プロトタイプを保持するための中間体を作成することです。

function extend(clazz, superclass) {
    var intermediate = function() {};
    intermediate.prototype = superclass.prototype;
    clazz.prototype = new intermediate();
    // Following line is optional, but useful
    clazz.prototype.constructor = clazz;
}

これにより、不要なコピーを回避できますが、コンストラクターで機能するオブジェクトをインスタンス化する必要がないことを意味します。また、instanceofを使用できるようにプロトタイプチェーンを設定します。また、一部の継承アンチパターンで発生する可能性のあるスーパークラスのプロトタイプ汚染も発生しません。

完全を期すために、サブクラスはそのコンストラクターでスーパークラスコンストラクターを呼び出す必要があります。これはで行うことができますSuperclass.call(this);

編集extend:ES5以降、への呼び出しをに置き換えることができます

Subclass.prototype = Object.create(Superclass.prototype);

同じことをします。

于 2011-05-13T11:35:32.557 に答える