0

私はこのコードを持っています:

function Stickman() {
    //some methods and properties

}

function JuniorStickman() {
    Stickman.call(this);
    this.p = new value // override a property in Stickman

}
JuniorStickman.prototype = new Stickman();

junior = new JuniorStickman();

このコードは、MDN の例から変更しました: https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript

私が理解していないのはこれです: call() と行

JuniorStickman.prototype = new Stickman() 

同じことをしているようです。行をコメントアウトすると

JuniorStickman.prototype = new Stickman();

私の JuniorStickman には、Stickman のすべてのメソッドとプロパティがまだあります。真実; 彼のプロトタイプ プロパティは現在、Stickman ではなく JuniorStickman ですが、問題ではないようです。

ジュニア スティックマン (ジュニア) にスティックマンのすべてのメソッドを持たせるには、ここでどのように作業を呼び出しますか? また、プロトタイプの割り当ては必要ですか?

私が理解しているように、 call() は実際には継承を与えていません。プロパティを追加/オーバーライドできる Stickman の一種のコピーを取得しています。これは正しいです?

4

3 に答える 3

3

私のジュニアスティックマンにスティックマンのすべてのメソッドを持たせるために、ここでどのように作業を呼び出しますか

コード内のコメントは、Stickmanコンストラクター内ですべてのプロパティ (メソッドも) を設定していることを示しているようです。したがって、新しいインスタンス ( ) を呼び出しStickmanて明示的に設定すると、内部に割り当てられているすべてのプロパティが新しいインスタンスに割り当てられます。thisJuniorStickmanStickman.call(this);thisStickman

.call [MDN]が行うことはthis、関数内で最初の引数を参照するように設定することだけです。例:

function foo() {
    alert(this.bar);
}

foo.call({bar: 42}); // alerts 42
foo.call({bar: 'baz'}); // alerts baz

では、なぜここで.call使われているのでしょうか? 他の言語での呼び出しと同じ役割を果たしsuper()ます。つまり、新しい子インスタンスで親コンストラクターを実行します。

プロトタイプの割り当てが必要か

それはあなたの場合ではありません。しかし通常、インスタンス間で共有する必要があるすべてのプロパティを関数のプロトタイプStickman.prototypeに割り当てます。たとえば、メソッドは通常、プロトタイプに割り当てられます。コンストラクターでは、各インスタンスに固有のプロパティのみを割り当てる必要があります。

この割り当てを行わない場合、 のインスタンスは、インスタンスのプロトタイプ チェーンにないため、JuniorStickman割り当てられたメソッドをまったく持ちません。Stickman.prototype


FWIW、親の新しいインスタンスをプロトタイプに割り当てて継承を設定することは最適な方法ではありません。必須の引数Stickmanが必要な場合はどうなりますか? あなたはどれを渡しますか?

Stickman現時点では、新しいインスタンスを作成する必要はありません。必要なのはStickman.prototype、プロトタイプ チェーンに持ち込むことだけです。Object.create これは[MDN]を使用して簡単に行うことができます:

JuniorStickman.prototype = Object.create(Stickman.prototype);
于 2013-04-01T23:56:16.833 に答える
0

Stickman() コンストラクターが新しいインスタンスごとに異なる処理を行う場合 (プロパティが作成された時刻と同じになるように設定されているとします)、JuniorStickman() の各インスタンスで、代わりに Stickman() コンストラクターを呼び出す必要があります。 Stickman() を呼び出してプロトタイプを設定したときからプロトタイプに保存されるタイムスタンプに依存します。

例えば:

function a() {
    this.time = new Date().getTime();
}

function b() {
    // a.call(this)
    this.hello = "something";
}

b.prototype = new a();

その行をコメントアウトすると、すべての新しい b() のタイムスタンプは同じになりますが、その行のコメントを外すと、希望どおりに動作します。

于 2013-04-01T23:58:10.263 に答える
0

JavaScript プロトタイプは、サブクラス化のようなものです。ただし、「子」オブジェクトのすべてのインスタンスは、1 つの親インスタンスを継承します。変更される複雑な値は、すべての子インスタンスで変更されます。

parent.call(thisContext) を使用すると、親の関数本体で this.somevar を使用して宣言された親の変数は、子の this コンテキストに初期化されるため、子のインスタンスに対して一意になります。parent.call(this しかない場合、子は親のインスタンスではないため、次のようになります。

(child instanceof parent) は、parent.call(this のみを使用する場合は false になります。

function parent(){
  this.arr=[];
  this.name="parent";
}
function child1(){
 parent.call(this);//sets all this elements 
                   //of parent to the current 
                   // instance of child1
}
child1.prototype = new parent();
function child2(){
}
child2.prototype = new parent();
var c1=new child1();
c1.name="c1"
c1.arr.push(["c1"]);
var anotherc1=new child1();
anotherc1.name="another c1";
anotherc1.arr.push("another c1");
var c2 = new child2();
c2.name="c2";
c2.arr.push(["c2"]);
var anotherc2 = new child2();
anotherc2.name="another c2";
anotherc2.arr.push(["another c2"]);
console.log(c1.name,c1.arr);//["c1"]
console.log(anotherc1.name,anotherc1.arr);//["anotherc1"]
console.log(c2.name,c2.arr);//["c2","anotherc2"]
console.log(anotherc2.name,anotherc2.arr);//["c2","anotherc2"]
console.log(c1 instanceof parent);//true
于 2013-04-02T00:15:42.870 に答える