個々のデータ構造から離れ、それらに対する反復について話しましょう。
前の章では、メソッド map.keys()
, map.values()
, map.entries()
を見ました。
These methods are generic, there is common agreement to use them for data structures. もし私たちが独自のデータ構造を作成することがあれば、それらも実装すべきです。
They are supported for:
Map
Set
Array
Plain Object も同様のメソッドをサポートしますが、構文は少し異なっています。
Object.keys, values, entries
プレーン オブジェクトでは、以下のメソッドが利用可能です。
- Object.keys(obj) – キーの配列を返します。
- Object.values(obj) – 値の配列を返します。
- Object.entries(obj) –
個のペアの配列を返します。
(例えばmapと比較して)区別することに注意してください。
Map | Object | |
---|---|---|
Call syntax | map.keys() |
Object.keys(obj) ですね。 obj.keys() ではなく |
Returns | iterable | “real” Array |
最初の違いは、Object.keys(obj)
と obj.keys()
でなく、”returns” を呼び出さなければならない点である。
なぜそうなるのでしょうか。 主な理由は柔軟性です。 オブジェクトは JavaScript のすべての複雑な構造のベースであることを思い出してください。 ですから、data
のような独自のオブジェクトを持っていて、そのオブジェクトは独自の data.values()
メソッドを実装しているかもしれません。 そして、その上で Object.values(data)
を呼び出すことができます。
2 番目の違いは、Object.*
メソッドは単なる反復処理ではなく、「本当の」配列オブジェクトを返すということです。 これは主に歴史的な理由によるものです。
たとえば、
let user = { name: "John", age: 30};
Object.keys(user) =
Object.values(user) =
Object.entries(user) = , ]
以下はプロパティ値をループするためのObject.values
を使用した例です。
let user = { name: "John", age: 30};// loop over valuesfor (let value of Object.values(user)) { alert(value); // John, then 30}
ちょうどfor..in
ループのように、これらのメソッドはキーとしてSymbol(...)
を使用するプロパティを無視します
通常それは便利です。 しかし、もしシンボル キーも必要なら、シンボル キーのみの配列を返す別のメソッド Object.getOwnPropertySymbols があります。 また、すべてのキーを返す Reflect.ownKeys(obj) というメソッドもあります。
Transforming objects
Object には、配列に存在する多くのメソッド、たとえば map
, filter
, その他。
それらを適用したい場合は、Object.entries
に続いてObject.fromEntries
を使用します:
-
Object.entries(obj)
を使ってobj
からキー/値ペアの配列を取得します。 - その配列に対して、
map
などの配列メソッドを使用します。 - 得られた配列に対して
Object.fromEntries(array)
を使用し、オブジェクトに戻してください。
例えば、価格を持つオブジェクトがあり、それを2倍にしたい場合、
let prices = { banana: 1, orange: 2, meat: 4,};let doublePrices = Object.fromEntries( // convert to array, map, and then fromEntries gives back the object Object.entries(prices).map(() => ));alert(doublePrices.meat); // 8
一見すると難しいですが、1、2回使えば簡単に理解できるはずです。 この方法で、強力な変換の連鎖を作ることができます。