2

var array = [1,2,undefined,4]; JavaScriptでは、: は次と同じであると考えられます 。

var array = [1,2];
array.length = 3;
array.push(4);

しかし、そうではありません。このコードはそれを示しています:

var array1 = [1,2];
array1.length = 3;
array1.push(4);

var array2 = [1,2,undefined,4];

traverseArray(array1);
traverseArray(array2);

function traverseArray(array) {
  console.log("trying: " + array);
  console.log("reduce:");
  array.reduce(function(prev, current, index, array) {
    if(current === undefined) {
      console.log("Found undefined");
    }
    console.log(index+": " +current);
  }, undefined);

  console.log("for loop:")
  for(var i=0;i < array.length;i++) {
    var current = array[i];
    console.log(i+": " +current);
  }
  console.log();
}

出力:

trying: 1,2,,4
reduce:
0: 1
1: 2
3: 4
for loop:
0: 1
1: 2
2: undefined
3: 4

trying: 1,2,,4
reduce:
0: 1
1: 2
Found undefined
2: undefined
3: 4
for loop:
0: 1
1: 2
2: undefined
3: 4

array1 の undefined が array2 の undefined と同じではないのはなぜですか? for ループは同じように動作するのに、reduce はそうではないのはなぜですか?

4

2 に答える 2

4

array1には、数値で名前が付けられた 3 つのプロパティがあります: 01、および3

array20には、1、 、 、の 4 つの数値名のプロパティ2があり3ます。という名前のプロパティの値は2たまたまundefinedです。

オブジェクトが持っていないプロパティの値をオブジェクトに尋ねると、結果は になりundefinedます。

ループではfor、各配列に 、012という名前のプロパティの値を要求します3。の場合array1、指定されたプロパティ2は存在しないため、プロパティ アクセスは を生成しundefinedます。の場合array2、プロパティ存在しますが、その値は実際に undefinedであるため、同じ結果が得られます。

一方、reduce実際に存在するプロパティに対してのみ動作します。ECMAScript 仕様 からreduce、カウンターを使用して配列をループする方法は次のkとおりです。

  1. k < lenの間、繰り返します
    • Pkを ToString( k ) とする
    • kPresentを、引数PkでOの [[HasProperty]] 内部メソッドを呼び出した結果とする
    • kPresentが true の場合、... [reduce 呼び出しにインデックス k の値を使用]

したがって、[[HasProperty]] チェックに合格した場合にのみインデックスが使用されることがわかります。array1には という名前のプロパティがない2ため、インデックスはスキップされます。

于 2015-02-20T18:59:14.560 に答える
3

apsillersはコメントでそれを釘付けにしました。. . 違いは、では配列の 3 番目の要素 (つまり、インデックス 2) にarray2実際に値を割り当てていることです。一方、 では、最初は 2 つの要素があり、長さプロパティを変更してから、3 番目の要素を4番目の位置。undefinedarray1

区別が重要である理由を説明する MDN の関連セクションを次に示します。

length プロパティを変更して配列を拡張しても、実際の要素の数は増加しません。たとえば、長さが現在 2 のときに長さを 3 に設定すると、配列には 2 つの要素しか含まれません。したがって、長さプロパティは、配列内の定義された値の数については何も言いません。

push メソッドは、長さプロパティに依存して、指定された値の挿入を開始する場所を決定します。

ここで重要なのは、lengthプロパティが本当に単純であり、配列の内容に継承的に関連付けられていないということです。私がそうであるかのように振る舞うのは、さまざまなメソッドがArrayたまたまそのプロパティを維持しているからです。

その結果、では、コードは に割り当てarray2た値を実際に報告していますが、では、コードは に値がないことを解釈しています。undefinedarray2[2]array1array1[2]undefined

于 2015-02-20T18:58:51.277 に答える