JavaScriptの Object と Map の違い・操作・entriesまとめ

JavaScriptにはキーと値のペアを扱う方法として `Object` と `Map` の2種類があります。本記事では、**ObjectとMapの違い・相互変換・基本操作・entries活用法**までを実用的に解説します。

---

## Object と Map の違い

| 比較項目         | `Object`                                   | `Map`                                      |
|------------------|---------------------------------------------|--------------------------------------------|
| 主な用途         | 静的なデータ構造、JSONなどのデータ管理        | 柔軟なキー・順序管理、キャッシュなど       |
| キーの型         | 文字列 または Symbol のみ                     | 任意の型（オブジェクト、関数などもOK）      |
| 順序の保証       | 挿入順の保証が不安定な場合もある              | 挿入順を厳密に保証                        |
| イテレーション   | `for...in` や `Object.keys()` が必要          | `map.forEach()` や `for...of` が使える      |
| 要素数の取得     | `Object.keys(obj).length`                    | `.size` プロパティで即取得可能              |
| JSON互換性       | JSON.stringify/parseで扱える               | 直接は不可、変換が必要                    |
| プロトタイプ継承 | あり（意図しないプロパティが入る可能性）      | なし（Mapは純粋なキー値コレクション）        |

---

## Object と Map の相互変換

### Object → Map

```js
const obj = { name: "Yuta", age: 30 };
const map = new Map(Object.entries(obj));
```

### Map → Object

```js
const map = new Map([
  ["name", "Yuta"],
  ["age", 30]
]);
const obj = Object.fromEntries(map);
```

---

## Objectの基本操作

```js
const obj = {};

// 追加・更新
obj.name = "Yuta";
obj["age"] = 30;

// 削除
delete obj.age;

// 存在確認
"name" in obj;
obj.hasOwnProperty("name");

// イテレーション
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}

// キー・値・エントリ取得
Object.keys(obj);
Object.values(obj);
Object.entries(obj);

// コピー
const copied = { ...obj };
const copied2 = Object.assign({}, obj);
```

---

## Mapの基本操作

```js
const map = new Map();

// 追加・更新
map.set("name", "Yuta");
map.set("age", 30);

// 値の取得
map.get("name");

// 存在確認
map.has("name");

// 削除・全削除
map.delete("age");
map.clear();

// サイズ取得
map.size;

// イテレーション
for (const [key, value] of map) {
  console.log(key, value);
}

map.forEach((value, key) => {
  console.log(`${key}: ${value}`);
});

// キー・値・エントリ取得
map.keys();
map.values();
map.entries();
```

---

## entriesとは？

### 概念と定義

`entries` とは、**「キーと値のペア（[key, value]）」の一覧を取得する仕組み**です。

### 目的とメリット

- オブジェクトやMapの内容をループ処理する
- `Object` や `Map` を `[key, value]` 形式で扱いたいときに便利
- フィルタや変換後の再構築にも活用できる

---

### entries が使える対象

| 対象     | メソッド                 | 結果の形式                      |
|----------|--------------------------|----------------------------------|
| Object   | `Object.entries(obj)`    | `[["key1", value1], ...]`        |
| Map      | `map.entries()`          | `{[key1, value1], ...}`   |
| Set      | `set.entries()`          | `{[value1, value1], ...}`|

---

### 使用例：Object.entries

```js
const obj = { name: "Yuta", age: 30 };

for (const [key, value] of Object.entries(obj)) {
  console.log(`${key}: ${value}`);
}
```

---

### 使用例：Map.entries

```js
const map = new Map([
  ["name", "Yuta"],
  ["age", 30]
]);

for (const [key, value] of map.entries()) {
  console.log(`${key}: ${value}`);
}
```

---

### 使用例：Set.entries

```js
const set = new Set(["a", "b"]);

for (const [key, value] of set.entries()) {
  console.log(key, value); // a a, b b
}
```

---

### よくある活用パターン

- `Object.entries` → `map()` → `Object.fromEntries()` で変換
- ネスト構造の平坦化
- キーに対するフィルタ・マッピング処理

---

## Object.entries を使ったマッピング処理

```js
const obj = { a: 1, b: 2, c: 3 };

const mapped = Object.fromEntries(
  Object.entries(obj).map(([key, val]) => [key, val * 2])
);

console.log(mapped); // { a: 2, b: 4, c: 6 }
```

---

## ネスト構造の変換（フラット化）

```js
const nested = {
  user: {
    name: "Yuta",
    info: {
      age: 30,
      city: "Tokyo"
    }
  }
};

function flatten(obj, prefix = "") {
  return Object.entries(obj).reduce((acc, [key, val]) => {
    const fullKey = prefix ? `${prefix}.${key}` : key;
    if (typeof val === "object" && val !== null && !Array.isArray(val)) {
      Object.assign(acc, flatten(val, fullKey));
    } else {
      acc[fullKey] = val;
    }
    return acc;
  }, {});
}

console.log(flatten(nested));
// {
//   'user.name': 'Yuta',
//   'user.info.age': 30,
//   'user.info.city': 'Tokyo'
// }
```

---

## entries系APIまとめ

| メソッド                  | 説明                                       | 対象        |
|---------------------------|--------------------------------------------|-------------|
| `Object.entries(obj)`     | Object → `[key, value]` の配列に変換       | Object      |
| `Object.fromEntries(arr)` | `[key, value]` 配列 → Object に変換        | 配列/Map    |
| `Map.entries()`           | Map のイテレータ（[key, value]）           | Map         |
| `Set.entries()`           | Set のイテレータ（[value, value]）         | Set         |

---

## 関連リンク

- [MDN: Object.entries](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)
- [MDN: Object.fromEntries](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries)
- [MDN: Object](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object)
- [MDN: Map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map)