あなたが達成しようとしていることはわかりません。のプロトタイプに「ドリルダウン」できる唯一の理由は、コンストラクターがプロパティを設定しておらず、暗黙のグローバルを作成しているためです。この行をフィドルに追加するだけです:sonB
console.log(age);//<--logs 31
sonB
コンストラクターによって設定されている値をログに記録します。プロトタイプ プロパティを取得する場合は、子のプロパティを削除するか、Object.getPrototypeOf()
メソッドを使用します。
明確にするために、これはデバッガーに固有のものではなく、JS がオブジェクトの値とプロパティを取得する方法に固有のものです。次のことを考慮してください。
var emptyObject = {};
console.log(emptyObject.someProperty);//logs undefined
Object.prototype.someProperty = 'YaY';
console.log(emptyObject.someProperty);//logs YaY
emptyObject.someProperty = function()
{
return Object.getPrototypeOf(this).someProperty;
};
console.log(typeof emptyObject.someProperty);//function
console.log(emptyObject.someProperty());//YaY again
delete(emptyObject.someProperty);//returns true
console.log(emptyObject.someProperty);//logs YaY.
これはどういう意味ですか: 簡単に言えば、任意のオブジェクト (配列、オブジェクト、関数、ロット) のプロパティにアクセスしようとすると、JS は最初にその特定のインスタンスにそのプロパティが定義されているかどうかを確認し、定義されていない場合は、JS の手順を実行します。プロトタイプチェーンのレベルを上げます。そのプロトタイプに要求されたプロパティがない場合、JS は次のプロトタイプにスキップします。プロパティが見つからなかった場合は、undefined
返されます。
したがって、コンストラクターが特定のプロパティを設定する場合、JS はプロトタイプを気にせず、できるだけ早くプロパティを返すのは当然のことです。
暗黙のグローバルにも同じロジックが適用されます。変数にvar
キーワードがない場合、JS はスコープ(現在の関数、「親」関数、最終的にはグローバル スコープ) をスキャンしてその変数を検索します。見つかった場合、その変数は使用されるか、再割り当てされます (コード内で何を行っているかによって異なります)。変数が見つからない場合は、JS が作成してくれます。悲しいことに、わざわざ現在の範囲に戻ることはありません。結果: グローバル変数が作成されます。
コードでは、Father
コンストラクターがインスタンスごとに新しい関数オブジェクトを作成します。この関数は、クロージャー変数 ( sirname
) とグローバル変数 ( firstname
) に依存しています。後者はによって設定されていませんSonA
、そのコンストラクターが新しいプロパティを割り当てるためです。SonB
ただし、 と の両方が共有するグローバル変数を作成しSonA
ますSonB
。
getName
のメンバー関数がFather
で動作している唯一の理由は、そのメソッドもスコープ スキャンと暗黙のグローバルsonB
に依存しているためです。
new SonB();//<-- constructor sets age and firstname globals
SonB.getName();//<-- ~= Father.getName.apply(SonB,arguments);
||
---> gets firstname global that was set in SonB constructor, uses that value
これですべてです。Father の getName メソッドを次のように再定義するだけです。
this.getName = function()
{//use this to point at calling context -> IE the instance on which the member function is being invoked
return this.firstname + ' ' + surname;
};