2

これら2つの呼び出しの違いは何だろうか:

var a = Array(1,2,3);
var b = new Array(1,2,3);

私はこのように動作を模倣しようとしました:

function test() {
  return {x:42};
}

var a = test();
var b = new test();
console.log(a,b); // the same

b同じようなことがどうして可能aですか?を使用する場合new、戻り値は無視する必要があります。

function test() {
  return 1;
}

var a = test();
var b = new test();
console.log(a,b); // 1 test{}
4

1 に答える 1

11

を使用して関数を呼び出すとnew、新しいオブジェクトが作成され、 として関数に渡されますthis。関数が何も返さない (またはプリミティブを返す) 場合、渡された新しいオブジェクトはnew式の結果です。ただし、関数がオブジェクトを返す場合、作成された新しいオブジェクトは破棄され、new代わりに関数によって返されるオブジェクトが式の結果になります。これは、仕様のセクション 11.2.2の乱暴な散文でカバーされています。これは、コンストラクターが何らかのキャッシュを保持し、引数が同一 (またはもちろんシングルトン) の場合にインスタンスを再利用する不変オブジェクトに最も役立ちます。

したがって、あなたの例では、test関数はオブジェクトを返すため、それを呼び出すnewだけで、オペレーターによって作成されたオブジェクトが作成され、破棄されnew、結果はtest代わりに返されるオブジェクトになります。

new別のオブジェクトを返す場合、からのオブジェクトが必ずしも「破棄される」とは言いません。コンストラクターは、オブジェクトが破棄されないようにするために、オブジェクトに対して何かを行う場合がありますnew。たとえば、コンストラクタは次のように記述できます。

function WeirdConstructor() {
    return {
        theNewObject: this
    };
}

...によって作成されたオブジェクトを受け取り、newそれが返すオブジェクトのプロパティにします。これを特別なシナリオと呼ぶのは控えめに言っても. :-)

Array(1, 2, 3)とのnew Array(1, 2, 3)両方が新しい配列を返すという事実は、実際にはArrayコンストラクターの特別な機能であり、セクション 15.4.1で説明されています。仕様では、標準コンストラクターを 経由で呼び出さない場合に、各標準コンストラクターが何をするかを慎重に説明していますnew。動作はさまざまです。それらの多くは型強制を行います.2つは、使用していなくてもArray使用したように動作し、本当に奇妙なことを行います(基本的に、現在の日付の文字列バージョンを提供します)。newDateString(new Date())


具体的Arrayには : どちらも使用しませんArray(1, 2, 3) または new Array(1, 2, 3). 私は使用します[1, 2, 3]。あいまいではありません (new Array(3)で空の配列を作成するlength = 3か、その中に , という 1 つのエントリを含む配列を作成し3ますかnew Array("3")?)、誰かが記号Arrayをシャドウできる可能性はありますが (可能性は低いですが)、リテラル形式をシャドウすることはできません。しかし、それがあなたの質問のポイントではなかったと思います。:-)

于 2013-05-21T10:15:32.650 に答える