ここでは、個々のデータ構造から離れて、それらの繰り返し処理について話しましょう。
前のチャプターで、map.keys(), map.values(), map.entries() と言うメソッドを見ました。
これらのメソッドは一般的なものであり、データ構造に対して利用することは共通認識です。そのため、もし独自のデータ構造を作成するときには、それらも実装しておく方がよいです。
これらは以下でサポートされています:
MapSetArray
通常のオブジェクトも同様のメソッドをサポートしますが、構文は少し異なります。
Object.keys, values, entries
通常のオブジェクトでは、次のメソッドが使えます。:
- Object.keys(obj) – キーの配列を返します。
- Object.values(obj) – 値の配列を返します。
- Object.entries(obj) –
[key, value]ペアの配列を返します。
しかし、それらの違いに注意してください(例として map との比較です。):
| Map | Object | |
|---|---|---|
| 構文 | map.keys() |
Object.keys(obj). obj.keys() ではありません。 |
| 戻り値 | iterable | “本当の” Array |
最初の違いは、obj.keys() ではなく、Object.keys(obj) と呼ぶ必要がある点です。
なぜそうなっているのでしょう?主な理由は柔軟性です。JavaScript ではオブジェクトはすべての複雑な構造のベースであることを忘れないでください。そのため、独自の order.values() メソッドを実装する order という独自のオブジェクトがあるかもしれません。それでも Object.values(order) を呼ぶことができます。
2つ目の違いは、Object.* メソッドが単なる iterable ではなく “本当の” 配列オブジェクトを返すことです。これは主に歴史的な理由です。
例:
let user = {
name: "John",
age: 30
};
Object.keys(user) = [name, age]Object.values(user) = ["John", 30]Object.entries(user) = [ ["name","John"], ["age",30] ]
ここの例では、Object.values を使って、プロパティの値をループします:
let user = {
name: "John",
age: 30
};
// 値のループ
for (let value of Object.values(user)) {
alert(value); // John, そして 30
}
for..in ループのように、これらのメソッドはキーとして Symbol(...) を使っているプロパティを無視します。
通常それは便利です。しかし、もしもこのようなキーも同様に扱いたい場合は、別のメソッド Object.getOwnPropertySymbols があります。これは Symbol を使っているキーのみの配列を返します。また、メソッド Reflect.ownKeys(obj) は すべての キーを返します。
オブジェクトの変換
オブジェクトには、配列に存在する多くのメソッドがありません。例えば map, filter など。
それらを適用したい場合は、Object.fromEntries に続いて、Object.entries が使用できます。:
Object.entries(obj)を使用してobjからキー/値ペアの配列を取得します。- その配列で、配列のメソッドを使用します。例えば
map - 結果の配列で
Object.fromEntries(array)を使用して、配列をオブジェクトに戻します。
例えば、価格をもつオブジェクトがあり、それらを2倍したいとします。:
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
// 配列に変換して map を実行、その後 fromEntries でオブジェクトに戻します
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
alert(doublePrices.meat); // 8
一見難しく見えますが、1,2回使うと簡単に理解できます。このようにして協力な変換のチェーンを作ることができます。
コメント
<code>タグを使ってください。複数行の場合は<pre>を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。