2021年11月2日 JavaScript (JS Primer) ループと反復処理(3)
配列のsomeメソッド
someメソッドを使うことで、配列の要素をテストします。テストがtrueになる要素が1つでもある場合、someメソッドはtrueを返します。テストはアロー関数で書きます。
const array = [1, 2, 3, 4, 5]; // 要素が2の倍数かテストする。 const even = (element) => element % 2 === 0; // 配列の少なくとも一つの要素で、コールバック関数の処理がtrueになるかをテストします。 // コールバック関数がtrueを返す場合、someメソッドがtrueを返す。 console.log(array.some(even)); // expected output: true
continue文
- while、do-while、forなどのループ処理の中で使うことができます。
- 対してbreakはfor文のループ自体をそのまま終わらせます。
- contenueはループ処理を最後まで行います。
- "スキップする" というイメージを持っておくと覚えやすいかも知れません。
配列のfilterメソッド
- 配列から特定の値だけを集めた新しい配列を作りたい場合にfilterメソッドを使います。
- 配列にコールバック関数の条件に合致するフィルターをかけて(trueのみフィルターを通る)新しい配列を作ります。
primerにあるコード例
function isEven(num) { return num % 2 === 0; } const array = [1, 5, 10, 15, 20]; console.log(array.filter(isEven)); // => [10, 20]
continue文を使った値の絞り込みはfilterメソッドを使うとより簡潔に書けます。
for...in文
for...in文は、オブジェクトのプロパティに対して反復処理を行います。
以下のコードではobjのプロパティ名をkey変数に代入して反復処理をしています。
const obj = { "a": 1, "b": 2, "c": 3 }; // 注記: ループのたびに毎回新しいブロックに変数keyが定義されるため、再定義エラーが発生しない。 for (const key in obj) { const value = obj[key] ; // 変数valueにそれぞれのバリューの値を入れています。 // keyは文字列のため、""はつけなくても良いです。 // key console.log(`key:${key}, value:${value}`); } (出力結果) // => key:a, value:1 // => key:b, value:2 // => key:c, value:3
for...in文が抱えている問題
for...in文は、対象となるオブジェクトのプロパティを列挙する場合に、親オブジェクトまで列挙可能なものがあるかを探索して列挙します。
そのため、オブジェクト自身が持っていないプロパティも列挙されてしまい、意図しない結果になる場合があります。
以下の例では親オブジェクトにhogeという関数を代入しています。
冒頭の記述と出力結果に注目してください。
const obj = { "a": 1, "b": 2, "c": 3 }; Object.prototype.hoge = function() {}; // 注記: ループのたびに毎回新しいブロックに変数keyが定義されるため、再定義エラーが発生しない。 for (const key in obj) { const value = obj[key] ; // バリューの値を入れている。 // keyは文字列のため、""はつけない。 // key console.log(`key:${key}, value:${value}`); } (出力結果) // => key:a, value:1 // => key:b, value:2 // => key:c, value:3 // => key:hoge, value:function() {}
おわかり頂けたでしょうか・・・
for..in文ではobjを参照しているのに、親オブジェクトに入っている関係のないhogeまで出力されてしまっています。
親オブジェクト自身がプロパティを持っている場合に意図しない結果を生んでしまうことになります。