2012-06-29 7 views
20

は考えてみましょう:未定義値アレイ(LEN)初期化子で

var a = Array(3); 
var b = [undefined,undefined,undefined]; 

a.mapb.mapは異なる結果を生成する理由は何ですか?

a.map(function(){ return 0; }); //produces -> [undefined,undefined,undefined] 
b.map(function(){ return 0; }); //produces -> [0,0,0] 
+1

関連:あなたはのb.length = 5 'に設定した場合どうなるかチェックしてください。あなたが 'map'を実行する前に、': '[0、0、0、未定義、未定義]'実際 – apsillers

答えて

23

配列コンストラクタは、指定された長さの配列を作成します。 ではなく、キーを作成します。 Array.prototype.mapのコールバック関数は、リスト内の要素に対してのみ実行されます。 、キーに関連付けられているすべての値(整数)0 ≤ iは < ある

  • Array(3)にはゼロキーがあるため、.mapのコールバックは実行されません。
  • [void 0, void 0, void 0]には、コールバック関数が実行される3つのキーがあります。

    Array(3).hasOwnProperty(0);     // false 
    [void 0, void 0, void 0].hasOwnProperty(0); // true 
    

明細書およびそのpolyfillは、MDNに記載されています。行47では、if (k in O) {は、存在しないキーがコールバック関数によって処理されないことを示しています。マップ機能が要素なし空の配列を生成するよう

+1

、マップを繰り返す必要があります0.array.length-1 –

+0

@ panda-34 0とnの間のキーをスキップすることは、テンキーの上を歩くことに似ています。 –

+0

@RobW 'Array(3)'は '3'要素を格納するためのメモリ*を実際には割り当てていないと仮定することができます。値は' undefined 'です。それは 'length'プロパティを単に' 3'に設定するだけですか? – Engineer

4

aは([[HasProperty] trueの場合のみ。仕様ごと、マップが結果を生成する)b、要素を持たない空の配列である3のアレイでありますmapは3つの要素の配列を生成します。 MDNから

6

コールバックのみ 値を割り当てた配列のインデックスのために呼び出されます。削除されたか、または に値が割り当てられていないインデックスに対しては呼び出されません。

配列aの場合、長さ3の配列をインスタンス化しましたが、値は割り当てられていません。 map関数は、割り当てられた値を持つ要素を検出しないので、新しい配列を生成しません。

配列bの場合、値がそれぞれundefinedの3つの要素の配列がインスタンス化されています。マップ関数は、割り当てられた値を持つ3つの要素を見つけ、新しい配列のそれぞれの新しい値として '0'を返します。

3

mapは、空のインデックスではなく既存のプロパティのみを繰り返します。

したがって、動作させたい場合は、最初に配列を入力する必要があります。

こと、例えば行うには複数の方法があります:apply

  • .fill()、ES6

    で導入

    console.log(new Array(3).fill().map(function(){ return 0; }));

  • コールconcat

    は、

    var arr = [].concat.apply([], new Array(3)); 
     
    console.log(arr.map(function(){ return 0; }));

  • 古いforループ。

    var arr = new Array(3); 
     
    for(var i=0; i<arr.length; ++i) arr[i] = 1; /* whatever */ 
     
    console.log(arr.map(function(){ return 0; }));

  • Most efficient way to create a zero filled JavaScript array?

  • エトセトラからいくつかのアイデアを使用してください。