かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript (ES2015) オブジェクトのループについてのメモ

ES2016/ES6でfor...ofが追加されたので改めてオブジェクトのループの方法を見直そうと思いました。

for..of

for...of 文は、iterableオブジェクトに対して反復的な処理をするループを作成します(iterableオブジェクトには組み込みのString, Array, 例えば Array に似たargumentsNodeListオブジェクト、TypedArray, Map, Set, ユーザー定義のiterableなどが含まれます)。

for..of と for...in の違い

  • for...of は値を列挙する
  • for...in はプロパティ(インデックス)を "prototypeで拡張されたプロパティを含めて" 列挙する

ex

Object.prototype.objCustomFunc = function() {};
Array.prototype.arrCustomFunc = function() {};
let arr = ['星宮いちご', '霧矢あおい', '紫吹蘭'];
arr.unitName = 'ソレイユ';

// for...of
for (let val of arr) {
  console.log(val);
}
// => "星宮いちご", "霧矢あおい", "紫吹蘭"

// for...in
for (let i in arr) {
  console.log(i);
}
// => 0, 1, 2, "unitName", "arrCustomFunc", "objCustomFunc"

// hasOwnProperty を使えば自身のプロパティだけに限定できる
for (let i in arr) {
  if ( iterable.hasOwnProperty(i) ) {
    console.log(i);
  }
}
// => 0, 1, 2, "unitName"

for...of でオブジェクトをそのままループさせることはできない

ObjectはiterableオブジェクトではないのでTypeErrorになる

let obj = {
  cute:   '星宮いちご',
  cool:   '霧矢あおい',
  sexy:   '紫吹蘭',
  pop:    '夏樹みくる',
  legend: '神前美月'
};
for (let val of obj) {
  console.log(val);
}
// => TypeError: obj is not iterable

Object.keys()でキーの配列をfor...ofでループさせる

let obj = {
  cute:   '星宮いちご',
  cool:   '霧矢あおい',
  sexy:   '紫吹蘭',
  pop:    '夏樹みくる',
  legend: '神前美月'
};
Object.prototype.objCustomFunc = function() {};

// for...of Object.keys(obj)
for (let key of Object.keys(obj)) {
  console.log(key, obj[key]);
}
// cute 星宮いちご
// cool 霧矢あおい
// sexy 紫吹蘭
// pop 夏樹みくる
// legend 神前美月

Array.forEachを使う方法

Object.keys(obj).forEach(function(key) {
  console.log(key, this[key]);
}, obj);
// cute 星宮いちご
// cool 霧矢あおい
// sexy 紫吹蘭
// pop 夏樹みくる
// legend 神前美月

Array.forEachで実行する関数をアロー関数()=>にすると、関数内のthisが第二引数で渡したオブジェクトにならないので、第二引数を使用する場合は注意が必要

for...in obj を使う方法

for...inならオブジェクトのままループさせることができるが、配列と同様でprototypeで拡張されたプロパティも列挙される

for (let key in obj) {
  console.log(key, obj[key]);
}
// cute 星宮いちご
// cool 霧矢あおい
// sexy 紫吹蘭
// pop 夏樹みくる
// legend 神前美月
// objCustomFunc [Function]
所謂 for 文でループさせる
let keys = Object.keys(obj);
for (let i = 0, l = keys.length; i < l; i += 1) {
  console.log(keys[i], obj[ keys[i] ]);
}
// cute 星宮いちご
// cool 霧矢あおい
// sexy 紫吹蘭
// pop 夏樹みくる
// legend 神前美月

まとめ

オブジェクトをループさせたい時

  1. for...of Object.keys(obj) でループさせる
  2. Object.keys(obj).forEach でループさせる ※ ループ中にbreakはできない
  3. for...in obj でループさせ適時 obj.hasOwnProperty(key)で自身のプロパティかチェックする
  4. for文でオブジェクトのキーをインデックス順に列挙してループさせる

ループ中にbreakもできるのでES2015/ES6が使える環境なら、for...ofでループさせるのが一番ラクかなと思いました。
IEfor...of未対応なようなので、IE11必須みたいなWEBサイト制作ではbabelとか使わないとダメですね... IE... ξ(Ծ‸Ծ)ξ


[参考]

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発