理解を深めるために8行目を追加して、実行を1行ずつ見ていきましょう。
/* 1 */ function Foo()
/* 2 */ {
/* 3 */ this.prop1 = 20;
/* 4 */ //some code
/* 5 */ }
/* 6 */
/* 7 */ var a = new Foo()
/* 8 */ var b = Foo()
1行目が実行されると、ヒープには1つの要素、という名前の関数オブジェクトが含まれるようになりますFoo
。この時点でFoo
は、は実行されていません。2行目から5行目は、この時点では実行されていませんが、Fooの本体として使用されています。Foo
呼び出されていないため、3行目はどのオブジェクトでも呼び出されていないため、。はありませんprop1
。
7行目が実行され、インタプリタはいくつかのことを行います。
- ヒープに新しいオブジェクトを追加します。
- このオブジェクトにのプロトタイプチェーンを提供します
Foo
。のプロトタイプにはFoo
何も割り当てていないので、これは特別なことではありませんが、から継承しているため、オブジェクトにはとのようなメソッドがあります。Foo
Foo
Object
hasOwnProperty
toString
- インタプリタは
Foo
、新しく作成されたオブジェクトをとして渡すことを呼び出しますthis
。
- 3行目が実行され、20という名前のプロパティが割り当てられ
prop1
ます。これが物理ヒープに新しいオブジェクトを作成するか、それともオブジェクトのプリミティブセクションに割り当てられるかは、インタプリタがすべてを最適化する方法に依存します。V8は、ヒープにオブジェクトを追加することを避けていると確信しています。
a
新しいオブジェクトは、の変数スコープで割り当てられますa
。
したがって、基本的に、関数を作成すると、関数ローダーがヒープ(または、スコープと最適化によってはスタック)にnew Foo
追加され、実行すると、新しいオブジェクトがスタックに追加されます。
しかし、使用しなかった場合はどうなりますnew
か?
楽しみのために、を使用しない場合のさまざまな動作を見てみましょうnew
。8行目が実行されると、new
呼び出していないため、通常の関数呼び出しを実行し、新しいオブジェクトを作成しません。次のことが起こります。
- 1行目で呼び出します
Foo
。厳密モードではないため、はグローバルオブジェクトthis
に割り当てられます。window
- 3行目が実行され、が割り当てられ
window.prop1 = 20
ます。
- 関数はを返します
undefined
。
b
に設定されundefined
ます。