1

JS オブジェクトの作成方法によって、Google Chrome デバッガーの動作がまったく異なることに気付きました。

このようなjsオブジェクトを作成すると;

var SonA = function(thename) {
               this.firstname = thename || "Graham";
               this.age = 31;
}

SonA.prototype = new Father();

次に、Chrome のデバッガーでは、ドリルダウンしてプロトタイプを表示することはできません。ただし、インスタンス変数の名前と年齢のキーと値のペアが得られます。

ただし、thisキーワードを省略すると、プロトタイプにドリルダウンできますが、インスタンス変数がデバッガーに表示されません。

//SonB doesn't use this keyword    
var SonB = function(thename) {
                  firstname = thename || "Graham";
                  age = 31;
           } 

SonB.prototype = new Father();
console.log(new SonA()); //this logs as: SonA {firstname: "graham", age: 31}
console.log(new SonB()); //this logs as as drill down object that shows the prototype

ここで何が起こっているのか、デバッガの動作が異なる理由を知っている人はいますか? 次の画像と jsfiddle は、問題をより明確に理解できるようにする場合があります。

スクリーンショット

http://jsfiddle.net/7z8sp/1/

4

3 に答える 3

2

あなたが達成しようとしていることはわかりません。のプロトタイプに「ドリルダウン」できる唯一の理由、コンストラクターがプロパティを設定しておらず、暗黙のグローバルを作成しているためです。この行をフィドルに追加するだけです: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;
};
于 2012-11-16T13:41:44.550 に答える
1

Console.dir()代わりに使用する: http://jsfiddle.net/7z8sp/3/

于 2012-11-16T13:33:35.577 に答える
1

24.0.1312.5 (公式ビルド 166104) ベータ版では、次のようになります。

SonA
    age: 31
    firstname: "Graham"
    __proto__: Father
        getName: function () {
        __proto__: Object

SonB
    __proto__: Father
        getName: function () {
        __proto__: Object

グローバル オブジェクト (この場合) にandthisを割り当てていないため、これは正しいことです。iframeのコンテキストで実行します。agefirstnamewindowresult

> firstname
"Graham"
> age
31
于 2012-11-16T13:36:37.963 に答える