1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【JavaScript】配列を for in で扱わないほうがよい

Posted at

よく言われていることですが、JavaScriptでfor inループを使うときは注意が必要です。
for in は、ただの for と違い、オブジェクトのプロパティがループの対象になるためです。
特に配列だと危険性が増します。

// 例えばこんな配列があって、、
var arr1 = ['a1', 'a2', 'a3'];
var arr2 = ['b1', 'b2', 'b3'];
var arr3 = ['c1', 'c2', 'c3'];

// さらに1つの配列に格納されていて、、
var arr = [arr1, arr2, arr3];

// すべての配列のひとつ目を取得したい
for (i in arr) {
    console.log(arr[i].shift());  // "a1" "b1" "c1"
}

ここでfor inの前でarrに関数を追加した場合、エラーが発生します。

arr.myFunc = function () {
    return 0;
}

for (i in arr) {
    console.log(arr[i].shift());  // "a1" "b1" "c1" "TypeError: arr[i].shift is not a function..."
}

これはprototypeに対しての追加でも同様です。

Array.prototype.myFunc = function () {
    return 0;
}

for (i in arr) {
    console.log(arr[i].shift());  // "a1" "b1" "c1" "TypeError: arr[i].shift is not a function..."
}

どうなっているかというと、インデックスにmyFuncがはいってきます。

for (i in arr) {
    console.log(i);  // "0" "1" "2" "myFunc"
}

素直にforループで書くほうが安全です。

// 配列の length は 3
console.log(arr.length); // 3

for (var i = 0; i < arr.length; i++) {
  console.log(arr[i].shift());  // "a1" "b1" "c1"
}

だれがどこで配列を拡張するかわかったもんじゃないです、はい。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?