1

私がやろうとしているのは、階層内の各オブジェクトが独自のプロパティ セットを持つ Javascript で単純なオブジェクト階層を作成すると同時に、新しく作成されたオブジェクトで instanceof を使用できるようにすることです。つまり、基本オブジェクト (以下の Person を参照) に実際に firstName プロパティと lastName プロパティを含めたいと考えました。最終的に、すべてのプロパティが同じ「これ」にマッシュされることは望んでいませんでした。私は素敵できちんとした真のオブジェクト階層が欲しいです。

これを行うには、これが正しいアプローチだと思いましたが、間違っているようです:

var Person = function (firstName, lastName)
{
    this.firstName = firstName;
    this.lastName = lastName;
}

var Ninja = function (beltColor)
{
    this.beltColor = beltColor;
}

Ninja.prototype = new Person ("George", "Clooney");
var ninja1 = new Ninja ("Black");

Ninja.prototype = new Person ("Scarlett", "Johansson");
var ninja2 = new Ninja ("Blue");

Ninja.prototype = new Person ("Brad", "Pitt");
var ninja3 = new Ninja ("Green");

console.log (ninja1 instanceof Ninja); // false
console.log (ninja1 instanceof Person); // true
console.log (ninja2 instanceof Ninja); // false
console.log (ninja2 instanceof Person); // true
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // true

上記のコード (私の考えでは) は、Ninja コンストラクターを使用して 3 つのメイン オブジェクトを効果的に作成し、結果のninja1.__proto__, ninja2.__proto__ and ninja3.__proto__オブジェクトには firstName/lastName プロパティが含まれます (これが必要です)。これらの __proto__ オブジェクトも「タイプ」Person になります。これらは Person コンストラクターで作成されたものであり、ninja1、ninja2、および ninja3 オブジェクトは「Ninja」タイプ (またはそう思った) です。コンストラクタ。

Person コンストラクターを介して新しく作成されたオブジェクトに Ninja.prototype を再割り当てすることは、instanceofオペレーターのスローであることを理解していますが、私の人生では、その理由はわかりません。

だから私は2つの質問があります:

1) Person コンストラクターを介して新しく作成されたオブジェクトに Ninja.prototype を再割り当てすると、instanceofオペレーターがスローされるのはなぜですか?
2) 私がやろうとしていることを行うための正しいアプローチは何ですか? 言い換えれば、プロパティが階層のさまざまなレベルにある単純なオブジェクト階層を作成し、instanceof意味のある方法で使用することもできますか?

4

3 に答える 3

1

ここでのinstanceOfメソッドは Ninja オブジェクトのコンストラクターを提供しません。これは、NInja オブジェクトのプロトタイプを "Person" として手動で割り当てたため、プロトタイプ チェーンをたどると Person オブジェクトを持つことになります。あなたが望むものを期待しているなら、以下のコードを試すことができます

var Person = function (firstName, lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }


var Ninja = function (firstName, lastName, beltcolor)
{
    this.beltColor = beltColor;
    Person.apply(this,arguments);
}

var ninja1 = new Ninja ( "George", "Clooney", "Black");

var ninja2 = new Ninja ("Scarlett", "Johansson","Blue");

var ninja3 = new Ninja ("Brad", "Pitt", "Green");

console.log (ninja1 instanceof Ninja); // true
console.log (ninja1 instanceof Person); // false
console.log (ninja2 instanceof Ninja); // true
console.log (ninja2 instanceof Person); // false
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // false
console.log(ninja1.firstName); //George

これがお役に立てば幸いです。

以下のリンクを参照することもできますhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain

于 2013-10-30T13:40:47.177 に答える
1

Q1: Person コンストラクターを介して新しく作成されたオブジェクトに Ninja.prototype を再割り当てすると、instanceofオペレーターがスローされるのはなぜですか?

これは、instanceofオペレーターがプロトタイプ チェーンを上っていき、オブジェクトの内部の実際のプロトタイプ ( [[Prototype]]) がコンストラクター関数の現在のプロトタイプ プロパティと比較されるかどうかをチェックすることによって機能するためです。

Q2: 私がやろうとしていることを行うための正しいアプローチは何ですか? つまり、プロパティが階層のさまざまなレベルにある単純なオブジェクト階層を作成すると同時に、instanceof意味のある方法で使用することもできますか?

プロトタイプは、コンストラクターのすべてのインスタンスに共通するアイテムを対象としています (たとえば、すべての人が脳を持っていますが、すべての人が同じ名前を持っているわけではありません)。プロトタイプを変更する代わりに、名と姓の引数をNinja関数のインスタンスのプロパティとして直接追加し、プロトタイプ プロパティをNinja空白にしますPerson(名前のない人のケースをカバーし、instanceoftrue を返すため):

var Person = function (firstName, lastName)
{   this.firstName = firstName;
    this.lastName = lastName;
}

var Ninja = function (beltColor, firstName, lastName)
{   this.beltColor = beltColor;
    Person.call(this, firstName, lastName); // call parent function
}

Ninja.prototype = new Person("", ""); // do this so that instanceof returns true

var ninja1 = new Ninja ("Black", "George", "Clooney");
var ninja2 = new Ninja ("Blue", "Scarlett", "Johansson");
var ninja3 = new Ninja ("Green", "Brad", "Pitt");

console.log (ninja1 instanceof Ninja); // true
console.log (ninja1 instanceof Person); // true
console.log (ninja2 instanceof Ninja); // true
console.log (ninja2 instanceof Person); // true
console.log (ninja3 instanceof Ninja); // true
console.log (ninja3 instanceof Person); // true
于 2013-10-30T13:26:11.483 に答える
0

オペレーターは、インスタンスのinstanceofキャッシュされたプロトタイプ チェーンを調べて、指定したコンストラクターと比較します。コンストラクターでプロトタイプを変更した場合、それらは一致しなくなります。

プロトタイプ オブジェクトを完全に変更せず、プロパティを更新するだけでは、それは起こりません。

あなたのオブジェクト モデルは奇妙に思えます。「ベルトの色」のように、名前がインスタンス プロパティにならないのはなぜですか?

于 2013-10-30T13:25:23.707 に答える