JavaScript 連想配列とは?オブジェクトとMapの使い方を完全解説

JavaScript

JavaScriptでプログラムを書いていると、「連想配列」という言葉を聞くことがあります。

「配列は知ってるけど、連想配列って何が違うの?」
「オブジェクトと連想配列は同じもの?」

この記事では、JavaScriptの連想配列について、初心者にもわかりやすく解説していきます。

スポンサーリンク
  1. JavaScriptに「連想配列」は存在しない?
  2. 連想配列(オブジェクト)とは
    1. 基本的な定義
    2. 通常の配列
    3. 連想配列(オブジェクト)
    4. 見た目の違い
  3. 連想配列の作り方
    1. 方法1:オブジェクトリテラル(最も一般的)
    2. 方法2:new Object()(あまり使われない)
    3. 方法3:Mapオブジェクト(ES6以降)
  4. 連想配列の基本操作
    1. 要素の追加
    2. 要素の取得
    3. 要素の更新
    4. 要素の削除
    5. 要素の存在確認
  5. 連想配列のループ処理
    1. for…in文(最も一般的)
    2. Object.keys()とforEach
    3. Object.entries()で分割代入
  6. 連想配列の便利なメソッド
    1. キーの数を取得
    2. すべてのキーを取得
    3. すべての値を取得
    4. オブジェクトをコピー
    5. オブジェクトをマージ
    6. オブジェクトを凍結(変更不可にする)
  7. 連想配列のソート
    1. キーでソート
    2. 値でソート
  8. JSONとの関係
    1. JSONとは
    2. オブジェクトをJSON文字列に変換
    3. JSON文字列をオブジェクトに変換
  9. オブジェクトとMapの違い
    1. オブジェクト(従来の方法)
    2. Map(ES6以降)
    3. どちらを使うべき?
  10. オブジェクトを連想配列として使う際の注意点
    1. 問題1:プロトタイプチェーンの影響
    2. 問題2:constructor、toString などの予約語
    3. 問題3:push()メソッドは使えない
  11. 配列との使い分け
    1. 配列を使う場面
    2. 連想配列(オブジェクト)を使う場面
  12. 実用的な使用例
    1. 例1:ユーザー情報の管理
    2. 例2:設定オプション
    3. 例3:データの集計
    4. 例4:複数のユーザーを管理
  13. まとめ

JavaScriptに「連想配列」は存在しない?

実は、JavaScriptには厳密には「連想配列」というデータ型は存在しません。

「え、じゃあ何を連想配列って呼んでるの?」と思いますよね。

JavaScriptで「連想配列」と呼ばれているのは、実際には以下の2つです:

  1. オブジェクト(Object) – 最も一般的
  2. Mapオブジェクト – ES6以降で追加

他のプログラミング言語(PHPやPythonなど)では「連想配列」や「辞書」と呼ばれる機能を、JavaScriptでは「オブジェクト」で実現しているんです。

そのため、JavaScriptにおいては「連想配列」=「オブジェクト」と考えて問題ありません。

連想配列(オブジェクト)とは

基本的な定義

連想配列は、「キー(key)」と「値(value)」のペアでデータを管理するデータ構造です。

通常の配列との違いを見てみましょう。

通常の配列

// 通常の配列
let fruits = ["りんご", "バナナ", "オレンジ"];

console.log(fruits[0]);  // "りんご"
console.log(fruits[1]);  // "バナナ"
console.log(fruits[2]);  // "オレンジ"

通常の配列では、数値のインデックス(0, 1, 2…)で要素にアクセスします。

連想配列(オブジェクト)

// 連想配列(オブジェクト)
let user = {
  name: "田中太郎",
  age: 25,
  email: "[email protected]"
};

console.log(user.name);   // "田中太郎"
console.log(user.age);    // 25
console.log(user.email);  // "[email protected]"

連想配列では、文字列のキー(name, age, email)で要素にアクセスします。

見た目の違い

  • 通常の配列[](角括弧)で囲む
  • 連想配列{}(波括弧)で囲む

連想配列の作り方

連想配列(オブジェクト)を作る方法は主に3つあります。

方法1:オブジェクトリテラル(最も一般的)

// 空のオブジェクトを作成
let person = {};

// または初期値を設定
let person = {
  name: "山田花子",
  age: 30,
  job: "エンジニア"
};

特徴:

  • 最もシンプルで読みやすい
  • 複数のプロパティを一度に定義できる
  • 改行して書くと可読性が上がる

方法2:new Object()(あまり使われない)

// 空のオブジェクトを作成
let person = new Object();

// プロパティを1つずつ追加
person.name = "佐藤次郎";
person.age = 28;
person.job = "デザイナー";

特徴:

  • 昔ながらの書き方
  • プロパティを後から追加する

方法3:Mapオブジェクト(ES6以降)

// Mapを使った連想配列
let person = new Map();

person.set("name", "鈴木一郎");
person.set("age", 35);
person.set("job", "営業");

console.log(person.get("name"));  // "鈴木一郎"

特徴:

  • より正確な連想配列の実装
  • キーに任意の型を使える
  • 挿入順序が保証される

連想配列の基本操作

要素の追加

let user = {
  name: "田中"
};

// ドット記法で追加
user.age = 25;

// ブラケット記法で追加
user["email"] = "[email protected]";

console.log(user);
// { name: "田中", age: 25, email: "[email protected]" }

2つの記法:

  • ドット記法user.age = 25(シンプル)
  • ブラケット記法user["email"](キーが変数や空白を含む場合に必須)

要素の取得

let user = {
  name: "田中太郎",
  age: 25
};

// ドット記法で取得
console.log(user.name);     // "田中太郎"

// ブラケット記法で取得
console.log(user["age"]);   // 25

// 変数をキーとして使う
let key = "name";
console.log(user[key]);     // "田中太郎"

要素の更新

let user = {
  name: "田中",
  age: 25
};

// 値を更新
user.age = 26;
user["name"] = "田中太郎";

console.log(user);
// { name: "田中太郎", age: 26 }

要素の削除

let user = {
  name: "田中",
  age: 25,
  email: "[email protected]"
};

// deleteで削除
delete user.email;

console.log(user);
// { name: "田中", age: 25 }

要素の存在確認

let user = {
  name: "田中",
  age: 25
};

// in演算子で確認
console.log("name" in user);    // true
console.log("email" in user);   // false

// hasOwnProperty()で確認(より安全)
console.log(user.hasOwnProperty("name"));   // true
console.log(user.hasOwnProperty("email"));  // false

連想配列のループ処理

for…in文(最も一般的)

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// キーを取得してループ
for (let key in user) {
  console.log(key + ": " + user[key]);
}

// 出力:
// name: 田中
// age: 25
// job: エンジニア

Object.keys()とforEach

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// キーの配列を取得してループ
Object.keys(user).forEach(function(key) {
  console.log(key + ": " + user[key]);
});

Object.entries()で分割代入

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// キーと値を同時に取得
for (let [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}

連想配列の便利なメソッド

キーの数を取得

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// キーの数を取得
let count = Object.keys(user).length;
console.log(count);  // 3

注意: オブジェクトにはlengthプロパティがないので、Object.keys()を使います。

すべてのキーを取得

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

let keys = Object.keys(user);
console.log(keys);
// ["name", "age", "job"]

すべての値を取得

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

let values = Object.values(user);
console.log(values);
// ["田中", 25, "エンジニア"]

オブジェクトをコピー

let user1 = {
  name: "田中",
  age: 25
};

// Object.assign()でコピー
let user2 = Object.assign({}, user1);

// スプレッド構文でコピー(ES6以降)
let user3 = {...user1};

// 元のオブジェクトには影響しない
user2.name = "山田";
console.log(user1.name);  // "田中"(変わらない)

オブジェクトをマージ

let basicInfo = {
  name: "田中",
  age: 25
};

let contactInfo = {
  email: "[email protected]",
  phone: "090-1234-5678"
};

// 2つのオブジェクトを結合
let user = Object.assign({}, basicInfo, contactInfo);

// またはスプレッド構文
let user = {...basicInfo, ...contactInfo};

console.log(user);
// {
//   name: "田中",
//   age: 25,
//   email: "[email protected]",
//   phone: "090-1234-5678"
// }

オブジェクトを凍結(変更不可にする)

let user = {
  name: "田中",
  age: 25
};

// オブジェクトを凍結
Object.freeze(user);

// 変更しようとしても無視される
user.age = 30;
console.log(user.age);  // 25(変わらない)

連想配列のソート

オブジェクトにはsort()メソッドがないため、一度配列に変換してからソートします。

キーでソート

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// キーをソート
let sortedKeys = Object.keys(user).sort();
console.log(sortedKeys);
// ["age", "job", "name"]

// ソートされたキーで新しいオブジェクトを作成
let sortedUser = {};
sortedKeys.forEach(function(key) {
  sortedUser[key] = user[key];
});

console.log(sortedUser);
// { age: 25, job: "エンジニア", name: "田中" }

値でソート

let prices = {
  apple: 150,
  banana: 80,
  orange: 120
};

// 値でソート(安い順)
let sortedPrices = Object.entries(prices)
  .sort(function(a, b) {
    return a[1] - b[1];  // 値で比較
  })
  .reduce(function(obj, [key, value]) {
    obj[key] = value;
    return obj;
  }, {});

console.log(sortedPrices);
// { banana: 80, orange: 120, apple: 150 }

JSONとの関係

連想配列(オブジェクト)は、JSONと非常に似た構文を持っています。

JSONとは

JSON(JavaScript Object Notation)は、JavaScriptオブジェクトの文字列表記法です。

オブジェクトをJSON文字列に変換

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};

// オブジェクトをJSON文字列に変換
let jsonString = JSON.stringify(user);
console.log(jsonString);
// '{"name":"田中","age":25,"job":"エンジニア"}'
console.log(typeof jsonString);  // "string"

JSON文字列をオブジェクトに変換

let jsonString = '{"name":"田中","age":25,"job":"エンジニア"}';

// JSON文字列をオブジェクトに変換
let user = JSON.parse(jsonString);
console.log(user.name);  // "田中"
console.log(typeof user);  // "object"

使用場面:

  • API通信でデータを送受信する
  • ローカルストレージにデータを保存する
  • ログに出力する

オブジェクトとMapの違い

ES6以降、JavaScriptには正式な連想配列としてMapオブジェクトが追加されました。

オブジェクト(従来の方法)

let user = {
  name: "田中",
  age: 25
};

user.job = "エンジニア";
console.log(user.name);  // "田中"

特徴:

  • キーは文字列またはSymbolのみ
  • 挿入順序が保証されない(数値キーは自動ソートされる)
  • プロトタイプチェーンの影響を受ける
  • シンプルで読みやすい

Map(ES6以降)

let user = new Map();

user.set("name", "田中");
user.set("age", 25);
user.set("job", "エンジニア");

console.log(user.get("name"));  // "田中"
console.log(user.size);         // 3(要素数)

特徴:

  • キーに任意の型を使える(オブジェクト、関数なども可能)
  • 挿入順序が保証される
  • プロトタイプチェーンの影響を受けない
  • sizeプロパティで要素数を取得できる
  • イテレータが使える

どちらを使うべき?

オブジェクトを使う場合:

  • シンプルなキー・バリューのデータ構造
  • JSONとの互換性が必要
  • 読みやすさを重視
  • キーが文字列で十分

Mapを使う場合:

  • キーに文字列以外の型を使いたい
  • 挿入順序を保持したい
  • 頻繁に要素を追加・削除する
  • プロトタイプチェーンの問題を避けたい

オブジェクトを連想配列として使う際の注意点

問題1:プロトタイプチェーンの影響

let user = {
  name: "田中"
};

// 存在しないはずのtoStringがある!
console.log("toString" in user);  // true(プロトタイプから継承)

解決策:hasOwnProperty()を使う

console.log(user.hasOwnProperty("toString"));  // false
console.log(user.hasOwnProperty("name"));      // true

問題2:constructor、toString などの予約語

let data = {};
data["constructor"] = "重要なデータ";

// constructorは元々オブジェクトが持っているプロパティ
console.log(data.constructor);  // [Function: Object](上書きされない場合がある)

解決策:Mapを使う

let data = new Map();
data.set("constructor", "重要なデータ");
console.log(data.get("constructor"));  // "重要なデータ"(安全)

問題3:push()メソッドは使えない

let user = {
  name: "田中"
};

// エラー:オブジェクトにはpush()メソッドがない
// user.push({age: 25});  // TypeError

正しい方法:

// 新しいプロパティを追加
user.age = 25;

// またはObject.assign()
Object.assign(user, {age: 25});

配列との使い分け

配列を使う場面

let colors = ["赤", "青", "緑"];
  • 順序が重要な場合
  • 数値インデックスでアクセスする場合
  • 同じ型のデータをまとめる場合
  • 配列専用メソッド(map(), filter(), reduce()など)を使いたい場合

連想配列(オブジェクト)を使う場面

let user = {
  name: "田中",
  age: 25,
  job: "エンジニア"
};
  • 意味のあるキー名でアクセスしたい場合
  • 異なる型のデータをまとめる場合
  • キー・バリューのペアでデータを管理したい場合
  • JSONとの互換性が必要な場合

実用的な使用例

例1:ユーザー情報の管理

let user = {
  id: 1001,
  name: "田中太郎",
  email: "[email protected]",
  age: 25,
  isActive: true,
  registeredAt: "2024-01-15"
};

// 情報の表示
console.log(`名前: ${user.name}`);
console.log(`メール: ${user.email}`);
console.log(`アクティブ: ${user.isActive ? "はい" : "いいえ"}`);

例2:設定オプション

let config = {
  theme: "dark",
  language: "ja",
  fontSize: 14,
  notifications: {
    email: true,
    push: false,
    sms: false
  }
};

// 設定の読み込み
if (config.theme === "dark") {
  // ダークモードを適用
}

// ネストされた設定へのアクセス
console.log(config.notifications.email);  // true

例3:データの集計

let salesData = {
  "2024-01": 150000,
  "2024-02": 180000,
  "2024-03": 200000
};

// 合計を計算
let total = Object.values(salesData).reduce(function(sum, value) {
  return sum + value;
}, 0);

console.log(`合計売上: ${total}円`);  // 合計売上: 530000円

例4:複数のユーザーを管理

let users = {
  "user001": {
    name: "田中太郎",
    age: 25
  },
  "user002": {
    name: "山田花子",
    age: 30
  },
  "user003": {
    name: "佐藤次郎",
    age: 28
  }
};

// 特定のユーザーを取得
console.log(users["user001"].name);  // "田中太郎"

// すべてのユーザーをループ
for (let userId in users) {
  console.log(`${userId}: ${users[userId].name}`);
}

まとめ

JavaScriptの連想配列について、重要なポイントをまとめます。

基本事項:

  • JavaScriptには厳密には「連想配列」は存在しない
  • 「連想配列」=「オブジェクト」と考えてOK
  • ES6以降はMapも利用可能

作成方法:

  • オブジェクトリテラル:{}(最も一般的)
  • new Object():あまり使われない
  • Map:new Map()(ES6以降)

基本操作:

  • 追加:obj.key = valueまたはobj["key"] = value
  • 取得:obj.keyまたはobj["key"]
  • 削除:delete obj.key
  • 確認:"key" in objまたはobj.hasOwnProperty("key")

ループ処理:

  • for...in
  • Object.keys()+forEach()
  • Object.entries()+for...of

便利なメソッド:

  • Object.keys():キーの配列を取得
  • Object.values():値の配列を取得
  • Object.entries():キー・値のペアの配列を取得
  • Object.assign():オブジェクトをマージ

注意点:

  • プロトタイプチェーンの影響を受ける
  • push()メソッドは使えない
  • キーは文字列またはSymbolのみ(Mapなら任意の型)

連想配列(オブジェクト)は、JavaScriptプログラミングの基本中の基本です。この記事で学んだ知識を活かして、効率的なデータ管理を実現しましょう!

コメント

タイトルとURLをコピーしました