DESIGNMAP

  1. TOP
  2. 公開講座
  3. ゼロから始めるJavaScript入門
  4. Mapオブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.18】

Mapオブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.18】

今回はECMAScript 2015で導入されたMapオブジェクトを学びます。

Mapオブジェクトは「キーと値」のセットを管理するオブジェクトです。キーは重複できません。
連想配列、ハッシュ、辞書ともいわれます。

以下の説明は「オブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.12】」、「コンストラクタ、オブジェクトを参照する変数 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.13】」、「プロトタイプ継承 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.14】」の知識を前提とします。

従来のJavaScriptには連想配列、ハッシュ、辞書は用意されていなく、オブジェクトリテラルで代用していました。

var person = {
	name: "太郎",
  	age: 5,
  	hobby: "読書"
}

このオブジェクトリテラルの場合、キーのデータ型は文字列型に暗黙に変換されます
また、プロトタイプ継承によりObject.prototypeオブジェクトのプロパティも継承されてしまいます。

補足すると下記のようなコードを書くことで、プロトタイプ継承をしない3つだけのプロパティをもつオブジェクトがつくれます。

let person = Object.create(null);
person.name = "太郎";
person.age = 40;
person.hobby = "読書";

値の追加と取得

実際にコードを書いていきましょう。
Atomで新規ファイルをつくり「文字列型 ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.2】」で作った「js-study」フォルダ内に、「map1.html」というファイル名で保存します。

以下のコードを書いて保存します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
  <script>
  
  let person = new Map();
  person.set("name", "太郎");
  person.set("age", 40);
  person.set("hobby", "読書");
  
  console.log(person.get("name"));
  console.log(person.get("age"));
  console.log(person.get("hobby"));
  
  console.log(person);

  </script>
  </body>
</html>

Google Chromeで「map1.html」を開き、JavaScriptコンソールを開きます。
以下のように表示されれば成功です。

Mapオブジェクトの内部構造をみてみましょう。
Map {"name" => "太郎", "age" => 40, "hobby" => "読書"}の左にある三角形を開きます。

sizeプロパティ、__proto__プロパティ、[[Entries]]プロパティの3つが表示されます。
sizeプロパティは要素の数です。__proto__プロパティはMap.prototypeオブジェクトを参照しています。[[Entries]]プロパティは内部属性です。

[[Entries]]プロパティはArrayオブジェクトを参照して、データは配列で管理されています。

let person = new Map();

Mapオブジェクトはリテラル値はなく、new演算子でMap()コンストラクタ関数を呼び出して生成します。

person.set("name", "太郎");

set()メソッドはMap.prototypeオブジェクトのメソッドで、値を追加します。キーと値のセットで追加します。

console.log(person.get("name"));

get()メソッドはMap.prototypeオブジェクトのメソッドで、キーを引数に渡すと、キーに対応した値が取得できます。

キーの重複はなく、値が上書きされる

set()メソッドで同じキーをセットした場合、値が上書きされます。

let person = new Map();
person.set("name", "太郎");
person.set("name", "二郎");

console.log(person.get("name"));

実行結果:

二郎

スポンサーリンク

キーはどんなデータ型でも可能

例えばキーをオブジェクト型にすることができます。

let person = new Map(),
    name = {},
    age = {},
    hobby = {}

person.set(name, "太郎");
person.set(age, 40);
person.set(hobby, "読書");

console.log(person);

実行結果:

Map {Object {} => "太郎", Object {} => 40, Object {} => "読書"}

MapオブジェクトのキーはObjectオブジェクトのまま保持されます。

サイズの取得、キーが存在するかの確認、キー/値の削除、すべてのキー/値を削除

Atomで新規ファイルをつくり「js-study」フォルダ内に、「map2.html」というファイル名で保存します。
以下のコードを書いて保存します。
<script>より前、</script>より後ろは「map1.html」と同じなのでコードの掲載を省略しています。

<script>
let person = new Map();
person.set("name", "太郎");
person.set("age", 40);
person.set("hobby", "読書");

console.log(person.size);
console.log(person.has("age"));
console.log(""); //出力結果をみやすくするため、空の行を出力するためのコードです

person.delete("name");
console.log(person.size);
console.log(person.has("name"));
console.log(person.get("name"));
console.log(""); 

person.clear();
console.log(person.size);
</script>
3
true

2
false
undefined

0

sizeプロパティは、Map.prototypeオブジェクトのプロパティで要素の数が取得できます。このプロパティは読み込み専用で代入はできません。

has()メソッドは、Map.prototypeオブジェクトのメソッドでキーが存在するかどうかをチェックします。キーが存在すればtrue、しなければfalseを返します。

delete()メソッドはMap.prototypeオブジェクトのメソッドで、特定のキーと値を削除します。

clear()メソッドはMap.prototypeオブジェクトのメソッドで、すべてのキーと値を削除して、Mapオブジェクトを空にします。

get()メソッドで存在しないキーを指定した場合は、エラーにならずundefinedが取得されることに注意してください。

キーの取得・存在確認のときはキーのデータ型もあわせる

キーを取得するときや、キーの存在を確認するときは、キーの名前だけでなくデータ型もあわせないと意図しない結果になります。

let person = new Map();
person.set("name", "太郎");
console.log(person.get(name));
console.log(person.has(name));

実行結果:

undefined
false

キーが文字列型ですので、取得するとき、存在を確認するときもキーを明示的に文字列型にする必要があります。

let person = new Map();
person.set("name", "太郎");
console.log(person.get("name"));
console.log(person.has("name"));

実行結果:

太郎
true

コンストラクタに配列を渡したMapオブジェクトの初期化

コンストラクタ関数に配列を渡すと、オブジェクト生成時にデータをMapオブジェクトに追加することができます。

let person = new Map([["name", "太郎"], ["age", 40], ["hobby", "読書"]]);
console.log(person);

実行結果:

Map {"name" => "太郎", "age" => 40, "hobby" => "読書"}

for ofループを使った中身の列挙

中身の列挙はfor ofループを使います。
Atomで新規ファイルをつくり「js-study」フォルダ内に、「map3.html」というファイル名で保存します。
以下のコードを書いて保存します。
<script>より前、</script>より後ろは「map1.html」と同じなので掲載を省略しています。

<script>
let person = new Map();
person.set("name", "太郎");
person.set("age", 40);
person.set("hobby", "読書");

//キーだけを取得して列挙
for (let v of person.keys()) {
  console.log(v);
}

console.log("");

//値だけを取得して列挙
for (let v of person.values()) {
  console.log(v);
}

console.log("");

//キーと値を同時に取得して列挙
for (let [k, v] of person) {
  console.log(k, v);
}
</script>

Google Chromeで「set3.html」を開き、JavaScriptコンソールを開きます。
以下のように出力されれば成功です。

name
age
hobby

太郎
40
読書

name 太郎
age 40
hobby 読書

forEach()メソッドを使った要素の操作

<script>
let person = new Map();
person.set("name", "太郎");
person.set("age", 40);
person.set("hobby", "読書");

person.forEach(function(value, key, obj){
    console.log(key, value);
});
</script>

出力結果:

name 太郎
age 40
hobby 読書

forEach()メソッドは、Mapの要素をforEach()メソッドの引数に渡した関数で順に処理できるMap.prototypeオブジェクトのメソッドです。

引数に渡した関数は、3つの仮引数を受けることができます。値、キー、オブジェクトの3つです。

3つめに渡されるオブジェクトの解説は「Setオブジェクト ー ゼロから始めるJavaScript入門(ECMAScript 2015)【Vol.17】」の説明をご覧ください。Mapオブジェクトの参照値がわたされます。

スポンサーリンク

関連記事

プロフィール

DESIGNMAP
ディレクター・Web制作者
ON VISITINGを制作・運営。
お問い合わせ