Map の型
Map
Mapはキーとそれに対応する値を保持する機能を持つ組み込みオブジェクトです。
キーとして任意の値を用いることができ、オブジェクトをキーとすることも可能です。
また、Mapの型はMap<K, V>のように表されます(Kはキーの型、Vは値の型です)。
Map の操作
Mapにキーと値を追加するにはsetメソッドを利用します。
Mapに格納された値を取得するgetメソッドや、引数として渡したキーがMapに保持されているかを判定できるhasメソッドなどもあります。
type KeyObj = { key: string }
const map: Map<string | KeyObj, number> = new Map()
const keyObj: KeyObj = { key: 'value' }
map.set(keyObj, 210)
console.log(map)
// Map (1) {{ "key": "value" } => 210}
console.log(map.has(keyObj))
// true
console.log(map.has({ key: 'value' }))
// false
{ key: 'value' }というオブジェクトをキーとしてMap に渡すことができています。
取り出すときには、setで登録したオブジェクトと同じ参照をもつオブジェクトを渡す必要があります。
同じ構造のオブジェクトを渡しただけでは、別のキーとしてみなされてしまうわけですね。
Mapの値を列挙する
Mapにはkeys、values、entriesといった、保持している値を列挙するためのメソッドも備わっています。
これらのメソッドの返り値はイテレータと呼ばれるもので、ループ処理での使用頻度が高いです。
const map: Map<string|KeyObj,number> = new Map()
type KeyObj = {key: string}
const keyObj: KeyObj = {key: 'value'}
map.set('key1',1234)
map.set(keyObj,210)
for(const key of map.keys()){
console.log(key)
}
//"key1"
//{"key": "value"}
for(const value of map.values()){
console.log(value)
}
//1234
//210
for(const[key, value] of map.entries()){
console.log(key)
console.log(value)
}
//"key1"
//1234
//{"key": "value"}
//210
WeakMap
Mapに似た組み込みオブジェクトにWeakMapというものがあります。
Mapと違って列挙を行うためのメソッド(keys、values、entries)を持たず、キーとしてはオブジェクト(もしくはnon-registered なシンボル)のみを設定することができ、数値や文字列を設定することはできません。
const weakMap = new WeakMap()
//Argument of type 'string' is not assignable to parameter of type 'object'.ts(2345)
weakMap.set('str','test')
//実行時エラーが発生(Invalid value used as weak map key)
ガベージコレクション
ガベージコレクションとは、使用しなくなったメモリを自動で解放する仕組みのことです。
WeakMapはこのガベージコレクションを目的として採用されることがあります。
WeakMapがMapと異なる点として、キーへの参照が弱参照である点があります。
このことは、キーとして設定できる値がオブジェクトかnon-registered なシンボルしか許されていない理由の一端となっています。
registered なシンボルはガベージコレクションの対象とならないため、WeakMapのキーとしての使用が許可されていないようです。
Because registered symbols can be arbitrarily created anywhere, they behave almost exactly like the strings they wrap. Therefore, they are not guaranteed to be unique and are not garbage collectable. Therefore, registered symbols are disallowed in WeakMap, WeakSet, WeakRef, and FinalizationRegistry objects.
Mapでキーとして使用されているオブジェクトは、Map自体がガベージコレクトされない限りはガベージコレクションの対象とならず、メモリ上に保持され続けます。
これは、Mapがキーを列挙するメソッドを持っているため、キーとして登録されたオブジェクトが不要になったと判断できないためです。