Edited at

JavaScript で [key, value] のループと分割代入を使ったループ


1. 調べようと思ったきっかけ

参考「非推奨の機能、廃止された機能 - JavaScript | MDN

何となく上のページを読んでいたら、



  • 分割代入型 for...in は非推奨です。代わりに for...of を使用してください。


とあったのですが、for...in のページを見ても「分割代入型 for...in」が何なのか書いてなかったので、気になって調べてみました。

(実は最近まで for...in が非推奨だと勘違いしていました… (汗


2. 分割代入型 for...in (非推奨)

普通の for...in は非推奨ではないですが、「分割代入型 for...in」は非推奨です。


分割代入型 for...in (非推奨)

// Array

const array = [['a', 1], ['b', 2], ['c', 3]];

console.log('array');
for (const [key, value] in array) { // ★
console.log({key, value});
}

// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);

console.log('map');
for (const [key, value] in map) { // ★
console.log({key, value});
}

// Object
const object = {'a': 1, 'b': 2, 'c': 3};

console.log('object');
for (const [key, value] in object) { // ★
console.log({key, value});
}


(もちろん [key, value] 以外にもコードがあり得ます)

※実行環境によりますが、このコードは正しく動作しないと思った方が良いです。


3. 分割代入型 for...of

こちらは使って大丈夫です。

(for...ofIterator を使った方法が非推奨、という情報がありますが、ここで言っているのは Iterator を使わない方法です)


3.1. Array

配列の要素を分割代入して使いたいときはそのまま回せます。


分割代入型 for...of

// Array

const array = [['a', 1], ['b', 2], ['c', 3]];

console.log('array');
for (const [key, value] of array) { // ★
console.log({key, value});
}



3.2. Array - Array.prototype.entries()

配列のインデックスを key にして回したいときは Array.prototype.entries() を使います。


分割代入型 for...of

// Array 2

const array2 = ['a', 'b', 'c'];

console.log('array2');
for (const [key, value] of array2.entries()) { // ★
console.log({key, value});
}



3.3. Map

Map はそのまま回すことができます。


分割代入型 for...of

// Map

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);

console.log('map');
for (const [key, value] of map) { // ★
console.log({key, value});
}


参考「Map で反復する - for...of - JavaScript | MDN


3.4. Object - Object.entries()

Object で Map と同じようなことがしたいときは Object.entries() を使います。


分割代入型 for...of

// Object

const object = {'a': 1, 'b': 2, 'c': 3};

console.log('object');
for (const [key, value] of Object.entries(obj)) { // ★
console.log({key, value});
}


Object.entries() は、ES8 の機能です。

日本語版の MDN だと「これは実験段階の機能です。」と出てきますが、英語版だと取り除かれています。

参考「Object.entries() - JavaScript | MDN」(日本語版)

参考「Object.entries() - JavaScript | MDN」(英語版)

Object.entries()Array.prototype.entries() とは違い、static メソッドです。


4. forEach()


4.1. Array - 分割代入

分割代入は関数の引数でも使えます。

ただし、アロー関数の場合、引数の括弧 () を省略できません。


forEach

// Array

const array = [['a', 1], ['b', 2], ['c', 3]];

console.log('array');
array.forEach(([key, value]) => { // ★
console.log({key, value});
});



4.2. Array

インデックスは普通の forEach() で取得できます。


forEach

// Array 2

const array2 = ['a', 'b', 'c'];

console.log('array2');
array2.forEach((value, key) => { // ★
console.log({key, value});
});


Array.prototype.entries()forEach() を使うことはできません。


4.3. Map

Map もそのまま forEach() で回せます。


forEach

// Map

const map = new Map([['a', 1], ['b', 2], ['c', 3]]);

console.log('map');
map.forEach((value, key) => { // ★
console.log({key, value});
});



4.4. Object - Object.entries() - 分割代入

Array.prototype.entries()forEach() で回せませんが、Object.entries() は回せます。


forEach

// Object

const object = {'a': 1, 'b': 2, 'c': 3};

console.log('object');
Object.entries(object).forEach(([key, value]) => { // ★
console.log({key, value});
});



5. key だけを回して value を取得


5.1. 普通の for...in

普通の for...in で key だけ取得して const value = foo[key]; のように value を取得する。


5.2. key 配列を使う

以下のコードで key 配列を取得し、for...offorEach() で key ごとに回し、const value = foo[key]; のように value を取得する。

Object.keys(array);

Map.prototype.keys();
Object.keys(object);