1

関数コンストラクターはjavascriptでオブジェクトを作成できますが、もっと基本的な質問があります。

次のような「関数宣言」を使用して、Javascriptでプレーン関数を宣言します。

function Foo() 
{
  this.prop1 = 20;
  //some code
}

これにより、ポインタがabc、prop1が20のJavaScriptヒープ内にオブジェクトが作成されますか?

または、関数コンストラクターが次のように呼び出された場合にのみオブジェクトが作成されるということですか?

var a = new Foo() //This definately creates a new object
4

4 に答える 4

3

javascriptでは、すべての関数はオブジェクトです。

あなたはこのようなことをすることができます:

function foo() {
    return true;
}

foo.greeting = "hello";
foo.tone = "mean";
foo.talk = function() {
    alert(foo.greeting);
}

foo.talk();

関数オブジェクトは、通常のjavascriptオブジェクトとすべて同じ機能を備えていますが、コンストラクターとして使用するなど、いくつかの追加機能を実行することもでき、いくつかの組み込みプロパティがあります。持つ他のプロパティ/メソッドの説明については、関数オブジェクトのMDNページを参照してください。

于 2012-06-24T06:07:06.503 に答える
2

関数宣言は関数オブジェクト を作成するだけで、関数を呼び出したり、そのインスタンスを作成したりするFooことはありません。

インスタンスは、実際に関数を呼び出したときにのみ作成され、newそれまでは、割り当てたプロパティはthisどこにも存在しません。

またFoo、コンストラクター関数として呼び出されることはありません。関数を見ただけでは、その関数がコンストラクター関数として使用されているかどうかを確実に知ることはできません。

于 2012-06-24T06:02:10.013 に答える
2

理解を深めるために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行目が実行され、インタプリタはいくつかのことを行います。

  1. ヒープに新しいオブジェクトを追加します。
  2. このオブジェクトにのプロトタイプチェーンを提供しますFoo。のプロトタイプにはFoo何も割り当てていないので、これは特別なことではありませんが、から継承しているため、オブジェクトにはとのようなメソッドがあります。FooFooObjecthasOwnPropertytoString
  3. インタプリタはFoo、新しく作成されたオブジェクトをとして渡すことを呼び出しますthis
  4. 3行目が実行され、20という名前のプロパティが割り当てられprop1ます。これが物理ヒープに新しいオブジェクトを作成するか、それともオブジェクトのプリミティブセクションに割り当てられるかは、インタプリタがすべてを最適化する方法に依存します。V8は、ヒープにオブジェクトを追加することを避けていると確信しています。
  5. a新しいオブジェクトは、の変数スコープで割り当てられますa

したがって、基本的に、関数を作成すると、関数ローダーがヒープ(または、スコープと最適化によってはスタック)にnew Foo追加され、実行すると、新しいオブジェクトがスタックに追加されます。

しかし、使用しなかった場合はどうなりますnewか?

楽しみのために、を使用しない場合のさまざまな動作を見てみましょうnew。8行目が実行されると、new呼び出していないため、通常の関数呼び出しを実行し、新しいオブジェクトを作成しません。次のことが起こります。

  1. 1行目で呼び出しますFoo。厳密モードではないため、はグローバルオブジェクトthisに割り当てられます。window
  2. 3行目が実行され、が割り当てられwindow.prop1 = 20ます。
  3. 関数はを返しますundefined
  4. bに設定されundefinedます。
于 2012-06-24T06:31:14.000 に答える
0

Javascriptは、関数がコンテキストなし/デフォルトの通常の関数であるため少し混乱しますが、newそれと組み合わせると新しいオブジェクトが作成されます。それで

function Foo() {
    this.prop1 = 20;
}

console.log( typeof(Foo) ); //-> 'function' 

タイプがFooというオブジェクトを作成しますfunction。これで、関数オブジェクトを取得して、現在のスタックに追加される新しいオブジェクトを作成できます。

var bar = new Foo();
console.log( typeof(bar) ); // -> 'object' with a pointer named prop1 to 20

これで2つのオブジェクトがFooあり、barこれはFooをコンストラクターとして使用して作成されたオブジェクトをnewで参照します。つまり、これnewは基本的に魔法であり、Javascriptでオブジェクトを作成する3つの方法の1つです。3つの方法は次のとおりです。

var object = {}; // Creates an object using object literal notation
new Foo(); // Creates an object with built in 'new'
Object.create(null); // new ECMA5 notation that avoid using new
于 2012-06-24T06:18:05.520 に答える