概要
JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。
「【JavaScript】JavaScript入門一覧」に他の記事をまとめています。
この記事で理解できること
- Map、WeakMapオブジェクトについて
- Map、WeakMapオブジェクトで使用できるメソッドについて
Map
- マップ型のコレクションを扱うためのビルトインオブジェクト。
- マップが持つ要素について挿入順で反復処理を行うことができる。
マップとは
キーと値の組み合わせからなる抽象データ型のこと。
※他のプログラミング言語の文脈では辞書やハッシュマップ、連想配列とも呼ばれる
マップの作成と初期化
- Mapオブジェクトをnewすることで、新しいマップを作成できる。
- コンストラクタの初期値として、
エントリーの配列
を渡すことができる。
エントリーとは
1つのキーと値の組み合わせを[キー, 値]という形式の配列で表現したもの。
const map = new Map();
// 作成した時点では何も持っていない
console.log(map.size); // => 0
// エントリーを定義
const entryNumbers = [["One", 1], ["Two", 2], ["Three", 3]];
const map = new Map(entryNumbers);
// 初期化後のサイズも反映されている
console.log(map.size); // => 3
値の追加と取り出し
以下のようなマップの要素を扱うメソッドが存在する。
メソッド | 概要 | 構文 | 返り値 |
---|---|---|---|
set | マップに新しい要素を追加 | myMap.set(key, value) | (要素が追加された)Mapオブジェクト |
get | マップが持つ特定のキーに紐づいた値を取り出す | myMap.get(key) | 指定されたキーに関連付けられた要素 |
has | マップが指定したvalueに紐づく要素を持っているか確認 | myMap.has(value) | 存在している場合「true」、存在しない場合「false」 |
delete | マップから指定したキーに紐づいた要素を削除 | myMap.delete(value) | 要素を削除できた場合「true」、指定した要素が存在しない場合「false」 |
clear | マップが持つすべての要素を削除 | myMap.clear() | undefined |
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
// 初期値のサイズ
console.log(myMap.size); // => 2
// 新しい要素の追加
myMap.set("key3", "value3");
console.log(myMap.size); // => 3
// 特定のキーにひもづいた値を取り出す
console.log(myMap.get("key3")); // => value3
// 指定したキーに紐づく要素を持っているか確認
console.log(myMap.has("key3")); // => true
console.log(myMap.has("key4")); // => false
// 指定したキーに紐づく要素を削除
console.log(myMap.delete("key3")); // => true
console.log(myMap.delete("key3")); // => false
// マップが持つすべての要素を削除
console.log(myMap.clear()); // => undefined
console.log(myMap.size); // => 0
マップの反復処理
- マップが持つ要素を反復処理するには、
forEach
、keys
、values
、entries
メソッドを使用する。 - また、Mapオブジェクト自身も
iterable
なオブジェクトであるためfor...of文
で反復処理が可能。
// Mapオブジェクト自身を反復処理
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
// Mapオブジェクトをfor..ofで反復処理
for (const map of myMap) {
console.log(map);
}
// => ['key1', 'value1']
// => ['key1', 'value1']
forEachメソッド
- forEachメソッドではマップが持つすべての要素を、
マップへの挿入順
に反復処理が可能。
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
// forEachでループ処理(コールバック関数の引数には値、キー、マップが渡される)
myMap.forEach((value, key, map) => {
console.log(`${key}: ${value}`);
});
// => key1: value1
// => key2: value2
keysメソッド
- keysメソッドはマップが持つすべての要素のキーを挿入順に並べたIteratorオブジェクトを返す。
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
for (const key of myMap.keys()) {
console.log(key);
}
// => key1
// => key2
valuesメソッド
- valuesメソッドはマップが持つすべての要素の値を挿入順に並べたIteratorオブジェクトを返す。
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
for (const value of myMap.values()) {
console.log(value);
}
// => value1
// => value2
entriesメソッド
- entriesメソッドはマップが持つすべての要素をエントリーとして挿入順に並べたIteratorオブジェクトを返す。
- エントリーは
[キー, 値]
のような配列のため、配列の分割代入
を使うとエントリーからキーと値を簡単に取り出せる。
const myMap = new Map([["key1", "value1"], ["key2", "value2"]]);
for (const [key, value] of myMap.entries()) {
console.log(`${key}:${value}`);
}
// => key1:value1
// => key2:value2
WeakMap
-
Map
と同様にマップ
を扱うためのビルトインオブジェクト。 - Mapと違う点は、キーを弱い参照(Weak Reference)で持つこと。
- キーは
オブジェクト
でなければならない。 -
WeakMap
内に格納されているオブジェクトへの参照が他にない場合、ガベージコレクションによりメモリ領域が解放される。
以下のようなマップの要素を扱うメソッドが存在する。(ここでのマップとはWeakMapのこと)
メソッド | 概要 | 構文 | 返り値 |
---|---|---|---|
set | マップに新しい要素を追加 | myWeakMap.set(オブジェクト, value) | (要素が追加された)Mapオブジェクト |
has | マップが指定したキーに紐づく要素を持っているか確認 | myWeakMap.has(key) | 存在している場合「true」、存在しない場合「false」 |
delete | マップから指定したキーに紐づいた要素を削除 | myWeakMap.delete(key) | 要素を削除できた場合「true」、指定した要素が存在しない場合「false」 |
const obj1 = {};
const obj2 = {};
const obj3 = {};
const myWeakMap = new WeakMap();
// 新しい要素の追加
myWeakMap.set(obj1, "value1");
myWeakMap.set(obj2, "value2");
// 指定したキーに紐づく要素を持っているか確認
console.log(myWeakMap.has(obj1)); // => true
console.log(myWeakMap.has({})); // => false
// 指定したキーに紐づく要素を削除
console.log(myWeakMap.delete(obj2)); // => true
console.log(myWeakMap.delete(obj3)); // => false