17

mapで作成された配列をpingした結果に混乱していますnew

function returnsFourteen() {
    return 14;
}

var a = new Array(4);
> [undefined x 4] in Chrome, [, , , ,] in Firefox
a.map(returnsFourteen);
> [undefined x 4] in Chrome, [, , , ,] in Firefox

var b = [undefined, undefined, undefined, undefined];
> [undefined, undefined, undefined, undefined]
b.map(returnsFourteen);
> [14, 14, 14, 14]

a.map(returnsFourteen)私は戻ることを期待していました(配列のMDNページによると:[14, 14, 14, 14]と同じです:b.map(returnsFourteen)

Arrayコンストラクターに渡される引数が0〜2 ** 32-1(両端を含む)の整数のみの場合、その数の要素を使用して新しいJavaScript配列が作成されます。

a私はそれが4つの要素を持つべき であることを意味すると解釈します。

ここで何が欠けていますか?

4

4 に答える 4

15

次のように配列を作成する場合:

var arr1 = new Array( 4 );

長さ の配列を取得しますが、要素4はありません。配列を変換しないのはそのためmapです。配列には変換する要素がありません。

一方、そうする場合:

var arr2 = [ undefined, undefined, undefined, undefined ];

長さも の配列を取得しますが、4要素は 4 つあります。

要素がない場合と、値が である要素がある場合の違いに注意してくださいundefinedundefined残念ながら、どちらの場合もプロパティ アクセサー式は値に評価されるため、次のようになります。

arr1[0] // undefined
arr2[0] // undefined

ただし、これら 2 つの配列を区別する方法があります。

'0' in arr1 // false
'0' in arr2 // true
于 2012-07-27T15:08:18.433 に答える
10
var a = new Array(4);

これは、明示的な長さ 4 で要素を持たない新しい配列オブジェクトを定義します。

var b = [undefined, undefined, undefined, undefined];

これは、暗黙的な長さ 4 の新しい配列オブジェクトを定義し、4 つの要素があり、それぞれの値は ですundefined

ドキュメントから:

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

arrayaの場合、値が割り当てられている要素がないため、何もしません。

arraybの場合、値が割り当てられた 4 つの要素 (はい、undefined値です) があるため、4 つの要素すべてを number にマップします14

于 2012-07-27T15:08:09.447 に答える
5

new Array(len)空の配列を作成し、値で埋めるのとは異なることを行います。undefined長さを に設定しますlen。したがって、次のコードに変換されます。

var newArr = [];
newArr.length = len;

楽しんでみましょうnewArr(と仮定してlen = 4):

newArr.length; //4
newArr[1] === undefined; //true
newArr.hasOwnProperty(1); //false

これは、 は 4 項目の長さですが、これらの 4 項目のいずれも含まれていないためです。空の弾丸クリップを想像してみてください。たとえば、20 個の弾丸を格納できるスペースがありますが、弾丸は含まれていません。それらは valueundefinedに設定されていませんでした。ただ... undefined です (これは少し紛らわしいです)。

これで、Array.prototype.map最初の配列に沿って喜んで歩き、さえずり、口笛を吹き、配列アイテムを見つけるたびに、その配列の関数を呼び出します。しかし、空の弾丸クリップに沿って歩くと、弾丸が見えません。確かに、弾丸の余地はありますが、それで弾丸が存在するわけではありません。ここでは、その値にマップするキーが存在しないため、値はありません。

値が入力されている 2 番目の配列undefinedの場合、undefinedであり、キーも同様です。またはの中に何かがありますが、その何かは定義されていません。キーがある限り、任意の値で動作します。b[1]b[3]Array.prototype.map

仕様でさらに検査するには:

于 2012-07-27T15:16:06.223 に答える
1

の動作に関する追加の回答が 1 つありconsole.logます。プレーンシンプル、出力は砂糖であり、技術的に間違っています。

この例を考えてみましょう:

var foo = new Array(4),
    bar = [undefined, undefined, undefined, undefined];

console.log( Object.getOwnPropertyNames(bar) );
console.log( Object.getOwnPropertyNames(foo) );

結果からわかるように、.getOwnPropertyNames関数は戻ります

["length"]

foo配列/オブジェクトの場合、しかし

["length", "0", "1", "2", "3"]

bar配列/オブジェクト用。

したがって、定義されているだけで実際のプロパティの割り当てがないconsole.log出力であなたをだますだけです。Arrays.length

于 2012-07-27T15:16:44.927 に答える