まとめ:このチュートリアルでは、キーと値をマッピングする 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); // trueCode 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); // adminCode language: JavaScript (javascript)存在しないキーを渡すと、get() メソッドは undefinedを返します。
let foo = {name: 'Foo'};
userRoles.get(foo); //undefinedCode language: JavaScript (javascript)キーによる要素の存在を確認する
マップ内にキーが存在するかどうかを確認するには、has() メソッドを使用します。
userRoles.has(foo); // false
userRoles.has(lily); // trueCode language: JavaScript (javascript)マップ内の要素数を取得する
size プロパティは Map オブジェクトのエントリ数を返します。
console.log(userRoles.size); // 3Code 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); // 0Code language: JavaScript (javascript)WeakMap
WeakMap は Map に似ていますが、WeakMap のキーはオブジェクトである必要があります。つまり、キー(オブジェクト)への参照がスコープ外になると、対応する値はメモリから自動的に解放されます。
WeakMap は Map オブジェクトのサブセットメソッドのみを持ちます。
-
get(key) -
set(key, value) -
has(key) -
delete(key)
ここでは Map と WeekMap の主な違いを示します。
- WeakMap の要素は反復処理できません。
- すべての要素を一度に消去できません。
- WeakMapのサイズを確認できません。
このチュートリアルでは、JavaScriptのMapオブジェクトを扱い、エントリを操作するための便利なメソッドについて学習しました。