4

私はJavaScriptを理解するために最善を尽くしています。これは、私を非常に混乱させるChromeコンソールでの簡単な実験です。

var foo=function(){this.p=1;}
foo.prototype.p=2;
var bar=new foo();
//foo{p:1,p:2} <- this is the output of Chrome console, from the last command above

Chrome の出力は、私を混乱させるものです。bar は、p:1 と p:2 の 2 つのパラメーターを持つオブジェクトのようです。これはバーが 2 p ということですか?この背後にある理由は何ですか?

4

5 に答える 5

2

bar オブジェクトには、値が 1 の p が 1 つだけあります

値 2 を持つ以前の p は、 getPrototypeOfでアクセスできる読み取り専用オブジェクトで表示できます。

Object.getPrototypeOf(bar).p

開発者ツールバーは、指定されたオブジェクトの XML 表現を出力するように設計されており、直接アクセスできるかどうかに関係なく、すべてのプロパティを直感的に表示できるため、両方が表示されます。

于 2013-09-15T10:30:17.710 に答える
2

はい。並べ替え。

bar両方を持っています:

  • 独自pプロパティ。

    bar.hasOwnProperty('p'); // true
    bar.p;                   // 1
    
  • 継承によってまだp残っているprototypeプロパティ。

    Object.getPrototypeOf(bar).p; // 2
    

barただし、一度に直接アクセスできるのはそのうちの 1 つだけであり、独自のプロパティが優先されます。

bar.p;        // 1
delete bar.p;
bar.p;        // 2

また、Chrome はプロトタイプ チェーンを走査し、列挙可能なプロパティを探しているため、両方を表示しています。

于 2013-09-15T10:32:03.123 に答える
2

Chrome DevTools コンソールのインライン (非拡張) オブジェクト表現では、現在、独自のプロパティと継承されたプロトタイプ プロパティの違いは表示されません。

では、何が起こっているのかを小さなステップに分けてみましょう。

new foo()内部protoプロパティが を指す新しいオブジェクトを作成しfoo.prototypeます。これは、このオブジェクトが で定義されているすべてのプロパティにアクセスできることを意味しますfoo.prototypeプロトタイプチェーンと呼ばれます。

オブジェクトに同じ名前のプロパティを設定すると、プロトタイプのプロパティが同じ名前で「シャドウ」され、通常のプロパティ アクセスでは後者にアクセスできなくなります (シャドウされたプロトタイプ プロパティにアクセスするために使用する @loxxy の回答を参照してくださいObject.getPrototypeOf(obj))。

関数をオブジェクトまたはそのプロトタイプに追加すると、コンソールで拡張オブジェクト表現を表示できますが、これはプロトタイプ プロパティとは独自のプロパティが異なります。q次の例では、この動作を可能にするメソッドをプロトタイプに追加しました。プロトタイプから継承されたプロパティは、オブジェクトのproto内部プロパティ内に表示されます。

ここに画像の説明を入力


コンストラクターのプロトタイプにインスタンス化されたオブジェクトの数だけが必要な場合は、次を使用できます。

var foo = function() {
    Object.getPrototypeOf(this).p++;
}
foo.prototype.p = 0;

console.log(new foo()); //{p: 1}
console.log(new foo()); //{p: 2}

または ES5 依存関係なし:

var foo = function() {
    foo.prototype.p++;
}
foo.prototype.p = 0;

console.log(new foo()); //{p: 1}
console.log(new foo()); //{p: 2}
于 2013-09-15T10:33:31.023 に答える
1

プロパティにアクセスすると、JavaScript エンジンはオブジェクト インスタンスで検索し、次にすべてのプロトタイプ チェーンで検索します。
したがって、プロトタイプ プロパティとしての p の意味は、クラスのインスタンスで定義するかどうかに関係なく、p のデフォルト値を持つことです。1 つの例として、車両の車輪の数が考えられます。たとえば、既定値は 4 です。
後でこのプロパティに書き込む場合:

 function Vehicle() {};
 Vehicle.protoype.wheelCount = 4;
 var myBike = new Vehicle();
 myBike.wheelCount = 2 ;           // this is a bike.

プロトタイプに設定された値を変更するのではなく、新しい値を持つインスタンスに新しいプロパティを作成します。たとえば、次のようになります。

 var myCar = new Vehicle();
 myCar.wheelCount // === 4

デフォルト値を設定し、コンストラクターでインスタンス値も設定するというまさにあなたが言及したシナリオは、 Object.getPrototypeOf を使用してデフォルト値に到達する必要があるため、あまり意味がありません。すべての言語に多くの可能性があるのと同様に、これは役に立たない可能性にすぎません。

于 2013-09-15T10:39:26.280 に答える