まとめ:このチュートリアルでは、キーと値をマッピングする JavaScript マップオブジェクトについて学習します。
JavaScript マップオブジェクトの概要
ES6 以前は、オブジェクトを使ってキーを任意の型の値にマッピングしてマップをエミュレートすることがよくありました。しかし、オブジェクトをマップとして使用すると、次のような副作用があります。
- オブジェクトには、プロトタイプなどのデフォルトキーが常にある。
- オブジェクトのキーは文字列またはシンボルでなければなりません。オブジェクトをキーとして使用することはできません。
- オブジェクトには、マップのサイズを表すプロパティはありません。
ES6 では、これらの欠点を解決するMap
と呼ばれる新しいコレクションタイプが提供されました。
定義によれば、Map
オブジェクトはキーと値のペアを保持します。キーはMap
のコレクション内で一意です。つまり、Map
オブジェクト内のキーは1回だけ表示されます。
マップのキーと値は任意の値にすることができます。
Map
オブジェクトを反復処理する場合、各反復処理は[キー、値]
の2メンバー配列を返します。反復処理の順序は挿入順序に従い、これは各キーと値のペアが初めてset()
メソッドによってマップに挿入された順序に対応します。
新しいMap
を作成するには、次の構文を使用します。
let map = new Map([iterable]);
Code language: JavaScript (javascript)
Map()
は、要素がキーと値のペアであるオプションのイテラブルオブジェクトを受け入れます。
JavaScript のマップに関する便利なメソッド
clear()
– マップオブジェクトからすべての要素を削除します。-
delete(キー)
– キーで指定された要素を削除します。要素がマップ内にある場合は true を返し、ない場合は false を返します。 -
entries()
– マップオブジェクト内の各要素の[キー、値]
の配列を含む新しいイテレーターオブジェクトを返します。マップ内のオブジェクトの順序は挿入順序と同じです。 -
forEach(コールバック[, thisArg])
– 挿入順序でマップ内の各キーと値のペアに対してコールバックを呼び出します。オプションの thisArg パラメーターは各コールバックのthis
値を設定します。 - get(キー) – キーに関連付けられた値を返します。キーが存在しない場合は undefined を返します。
- has(キー) – キーに関連付けられた値が存在する場合は true を返し、それ以外の場合は false を返します。
-
keys()
– 挿入順序で要素のキーを含む新しいイテレーターを返します。 -
set(キー、値)
– マップオブジェクト内のキーの値を設定します。これはマップオブジェクト自体を返すため、このメソッドを他のメソッドで連結できます。 -
values()
は、挿入順序で各要素の値を含む新しいイテレーターオブジェクトを返します。
JavaScript マップの例
マップオブジェクトを使用した例をいくつか紹介します。
新しいマップオブジェクトを作成する
次のようにuser
オブジェクトのリストがあるとします。
let john = {name: 'John Doe'},
lily = {name: 'Lily Bush'},
peter = {name: 'Peter Drucker'};
Code language: JavaScript (javascript)
ユーザーとロールのマップを作成する必要があると想定しましょう。この場合、次のコードを使用します。
let userRoles = new Map();
Code language: JavaScript (javascript)
userRoles
は Map
オブジェクトのインスタンスであり、その型は次の例で示すようにオブジェクトです。
console.log(typeof(userRoles)); // object
console.log(userRoles instanceof Map); // true
Code language: JavaScript (javascript)
Map に要素を追加する
ユーザーにロールを割り当てるには、set()
メソッドを使用します。
userRoles.set(john, 'admin');
Code language: JavaScript (javascript)
set()
メソッドはユーザーの john
と admin
ロールをマップします。set()
メソッドはチェーン可能なので、この例に示すように少しタイピングを節約できます。
userRoles.set(lily, 'editor')
.set(peter, 'subscriber');
Code language: JavaScript (javascript)
イテラブルオブジェクトを使用してマップを初期化する
前述のように、Map()
コンストラクターにイテラブルオブジェクトを渡すことができます。
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber']
]);
Code language: JavaScript (javascript)
キーによるマップから要素を取得する
John
のロールを確認したい場合は、get()
メソッドを使用します。
userRoles.get(john); // admin
Code language: JavaScript (javascript)
存在しないキーを渡すと、get()
メソッドは undefined
を返します。
let foo = {name: 'Foo'};
userRoles.get(foo); //undefined
Code language: JavaScript (javascript)
キーによる要素の存在を確認する
マップ内にキーが存在するかどうかを確認するには、has()
メソッドを使用します。
userRoles.has(foo); // false
userRoles.has(lily); // true
Code language: JavaScript (javascript)
マップ内の要素数を取得する
size
プロパティは Map オブジェクトのエントリ数を返します。
console.log(userRoles.size); // 3
Code language: JavaScript (javascript)
マップキーを反復処理する
Map
オブジェクトのキーを取得するには、keys()
メソッドを使用します。keys()
は、マップ内の要素のキーを含む新しいイテレーターオブジェクトを返します。
次の例は、userRoles
マップオブジェクト内のユーザーのユーザー名を表示します。
let john = { name: 'John Doe' },
lily = { name: 'Lily Bush' },
peter = { name: 'Peter Drucker' };
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber'],
]);
for (const user of userRoles.keys()) {
console.log(user.name);
}
Code language: JavaScript (javascript)
出力
John Doe
Lily Bush
Peter Drucker
マップ値を反復処理する
同様に、values()
メソッドを使用して、マップ内のすべての要素の値を含むイテレーターオブジェクトを取得できます
let john = { name: 'John Doe' },
lily = { name: 'Lily Bush' },
peter = { name: 'Peter Drucker' };
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber'],
]);
for (let role of userRoles.values()) {
console.log(role);
}
Code language: JavaScript (javascript)
出力
admin
editor
subscriber
マップ要素を反復処理する
また、entries()
メソッドは、Map
オブジェクト内の各要素の [key,value]
の配列を含むイテレーターオブジェクトを返します
let john = { name: 'John Doe' },
lily = { name: 'Lily Bush' },
peter = { name: 'Peter Drucker' };
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber'],
]);
for (const role of userRoles.entries()) {
console.log(`${role[0].name}: ${role[1]}`);
}
Code language: JavaScript (javascript)
反復処理をより自然にするには、次のように分解を使用できます。
let john = { name: 'John Doe' },
lily = { name: 'Lily Bush' },
peter = { name: 'Peter Drucker' };
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber'],
]);
for (let [user, role] of userRoles.entries()) {
console.log(`${user.name}: ${role}`);
}
Code language: JavaScript (javascript)
for...of
ループに加えて、マップオブジェクトの forEach()
メソッドを使用できます。
let john = { name: 'John Doe' },
lily = { name: 'Lily Bush' },
peter = { name: 'Peter Drucker' };
let userRoles = new Map([
[john, 'admin'],
[lily, 'editor'],
[peter, 'subscriber'],
]);
userRoles.forEach((role, user) => console.log(`${user.name}: ${role}`));
Code language: JavaScript (javascript)
マップキーまたは値を配列に変換する
イテラブルオブジェクトではなく配列を使用したい場合、スプレッド演算子を使用できます。
次の例は、各要素のキーをキーの配列に変換します。
var keys = [...userRoles.keys()];
console.log(keys);
Code language: JavaScript (javascript)
出力
[ { name: 'John Doe' },
{ name: 'Lily Bush' },
{ name: 'Peter Drucker' } ]
Code language: JavaScript (javascript)
次の例は、要素の値を配列に変換します。
let roles = [...userRoles.values()];
console.log(roles);
Code language: JavaScript (javascript)
出力
[ 'admin', 'editor', 'subscriber' ]
Code language: JSON / JSON with Comments (json)
キーによる要素を削除する
マップ内のエントリを削除するには、delete()
メソッドを使用します。
userRoles.delete(john);
Code language: CSS (css)
マップ内のすべての要素を削除する
Map
オブジェクト内のすべてのエントリを削除するには、clear()
メソッドを使用します。
userRoles.clear();
Code language: CSS (css)
したがって、マップのサイズは الآن になりました。
console.log(userRoles.size); // 0
Code language: JavaScript (javascript)
WeakMap
WeakMap
は Map
に似ていますが、WeakMap
のキーはオブジェクトである必要があります。つまり、キー(オブジェクト)への参照がスコープ外になると、対応する値はメモリから自動的に解放されます。
WeakMap
は Map
オブジェクトのサブセットメソッドのみを持ちます。
-
get(key)
-
set(key, value)
-
has(key)
-
delete(key)
ここでは Map
と WeekMap
の主な違いを示します。
- WeakMap の要素は反復処理できません。
- すべての要素を一度に消去できません。
- WeakMapのサイズを確認できません。
このチュートリアルでは、JavaScriptのMapオブジェクトを扱い、エントリを操作するための便利なメソッドについて学習しました。