2

OOP JavaScript に関する私の限られた経験から、異なるプロパティを持つ複数のオブジェクトを処理する一般的な方法ですが、同じメソッドは次のようにコンストラクターを使用します。

function Animal ( type ) {
    this.type = type
};
Animal.prototype.sayHello = function () {
    return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );

ここでの私の理解はgoat、の関数を継承/参照することですAnimal

上記を次のオブジェクト リテラル概念で複製できると思います

var Animal = {
    type : '',
    sayHello : function () {
        return 'Hi, I am a ' + this.type
    }
}
var goat = Object.create( Animal );
goat.type = 'Goat';

ここで継承がAnimal失われるのでしょうか、それともGoatまだAnimalメソッドを参照していますか?

コンストラクター/クラスを複製するObject.create()代わりに使用して問題があるかどうかを知りたいです。newパフォーマンス オフセットまたは使用を続ける理由はありnewますか?

アドバイスをいただければ幸いです。明確化が必要な場合は、喜んで質問に追加します。

更新されたオブジェクトの作成

var Animal = {
    sayHello : function () {
        return 'Hi, I am a ' + this.type
    }
}
var goat = Object.create( Animal, { 'type' : { value: 'goat' } } );
4

1 に答える 1

6

...異なるプロパティを持つ複数のオブジェクトを処理する一般的な方法ですが、同じメソッドはコンストラクターを使用します...

はい、他の一般的な方法は (ご覧のとおり)Object.createです。

ここでの私の理解はgoat、の関数を継承/参照することですAnimal

そうではありません。new Animal式では、goatによって参照されるオブジェクトがAnimal.prototypeその基になるプロトタイプとして割り当てられます。への直接接続はなく、 への接続AnimalのみAnimal.prototypeです。(は通常、そのプロパティを介してAnimal.prototype参照されますが、誰かが新しいオブジェクトを に割り当てると、そのリンクが壊れる可能性があります。)AnimalconstructorAnimal.prototype

ここで継承がAnimal失われるのでしょうか、それともGoatまだAnimalメソッドを参照していますか?

コンストラクター以外の例でgoatAnimal、その基になるプロトタイプとして取得されるため、それ自体で見つからないプロパティについてgoat、JavaScript エンジンはそれAnimalがあるかどうかを確認します。あなたの例では、それは from を使用していることを意味しますが、独自の を持っているため、を使用していません。goatsayHelloAnimaltypegoattype

これに相当するものは次のとおりです。

function Animal ( type ) {
    this.type = type
};
Animal.prototype.sayHello = function () {
    return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );

...Object.create代わりにプロトタイプを設定するために使用すると、次のようになります。

var animalPrototype = {
    sayHello: function () {
        return 'Hi, I am a ' + this.type
    }
};
function createAnimal(type) {
    var rv = Object.create(animalPrototype);
    rv.type = type;
    return rv;
};
var goat = createAnimal( 'Goat' );

あなたのコメントについて:

animalPrototype内部createAnimalと呼び出しを含む問題はありますObject.create(this.animalPrototype)か?

これを意味する場合:

function createAnimal(type) {
    var animalPrototype = {                       // Issue #1
        sayHello: function () {
            return 'Hi, I am a ' + this.type
        }
    };
    var rv = Object.create(this.animalPrototype); // Issue #2
    rv.type = type;
    return rv;
};
var goat = createAnimal( 'Goat' );

...では、はい、2 つの問題があります。

  1. への呼び出しごとに新しい を作成しますが、これは目的を無効にし、 2.への呼び出し内では、グローバル オブジェクト (ルース モード) または(厳密モード) のいずれかになるため、おそらく必要な式ではありません。animalPrototypecreateAnimalthiscreateAnimalundefinedthis.animalPrototype

あなたはこれを行うことができます:

function createAnimal(type) {
    var rv = Object.create(createAnimal.proto);
    rv.type = type;
    return rv;
};
createAnimal.proto = {
    sayHello: function () {
        return 'Hi, I am a ' + this.type
    }
};
var goat = createAnimal( 'Goat' );

もちろん、これはコンストラクター関数に非常によく似ているため、混乱を招く可能性があります。

于 2013-08-28T07:21:48.230 に答える