こんにちは、かつコーチです。
前回は map ・ filter ・ reduce を使った配列の加工方法を解説しました。
その中でも何度か登場していた「オブジェクト」について、今回はあらためて基本からしっかり解説していきます。
配列と並んで、JavaScriptでデータを扱ううえで欠かせない存在なので、ここでしっかり整理しておきましょう。
オブジェクトとは?
名前とデータをセットで管理する箱
オブジェクト(Object) とは、「名前(キー)」と「値(バリュー)」をセットで管理できるデータの入れ物です。
配列が「順番」でデータを管理するのに対し、オブジェクトは「名前」でデータを管理するとイメージすると分かりやすいです。
const user = {
name: "かつコーチ",
age: 30,
isAdmin: false,
};
name や age のように、何のデータなのかが名前で分かるため、配列よりも「意味のあるまとまり」を表すのに向いています。
配列との使い分け
配列とオブジェクトはどちらも複数のデータをまとめられますが、向いている用途が異なります。
| データの種類 | 向いている入れ物 | 例 |
|---|---|---|
| 同じ種類のデータが並ぶ | 配列 | 果物の名前リスト、ユーザーの一覧 |
| 1つのものが複数の性質を持つ | オブジェクト | 1人のユーザーの名前・年齢・メールアドレス |
「同じ種類のものがたくさん並ぶなら配列」「1つのものの詳細情報をまとめるならオブジェクト」と覚えておくと、使い分けに迷いにくくなります。
そして実務では、この2つを組み合わせた「オブジェクトの配列」(前回の記事で登場した users のような形)が非常によく登場します。
オブジェクトを作る・値にアクセスする
オブジェクトリテラルでの作成
オブジェクトは { }(波括弧)を使い、キー: 値 の形で作成します。
const product = {
name: "ノートPC",
price: 80000,
inStock: true,
};
キーは基本的に文字列ですが、シンプルな名前であればクォートを省略できます(内部的には文字列として扱われます)。
ドット記法とブラケット記法
オブジェクトの値にアクセスする方法は2種類あります。
const product = {
name: "ノートPC",
price: 80000,
};
// ドット記法
console.log(product.name); // ノートPC
// ブラケット記法
console.log(product["price"]); // 80000
普段はシンプルに書ける ドット記法 を使うのが基本です。
ただし、キー名が変数に入っている場合や、キー名にハイフンなど特殊な文字が含まれる場合は、ブラケット記法 を使う必要があります。
const product = {
name: "ノートPC",
price: 80000,
};
const key = "price";
console.log(product[key]); // 80000(ドット記法だとproduct.keyになりエラーになる)
プロパティの追加・更新・削除
値を追加・更新する
オブジェクトに新しいプロパティを追加したり、既存の値を更新したりするのはとてもシンプルです。
const user = {
name: "かつコーチ",
};
user.age = 30; // 新しいプロパティを追加
user.name = "かつコーチ(更新)"; // 既存のプロパティを更新
console.log(user); // { name: "かつコーチ(更新)", age: 30 }
const で宣言していても、オブジェクトの 中身(プロパティ) は変更できる点に注意してください。
const が禁止しているのは「変数の再代入」であって、「オブジェクトの中身の変更」ではありません。
プロパティを削除する
プロパティを削除するには delete 演算子を使います。
const user = {
name: "かつコーチ",
age: 30,
};
delete user.age;
console.log(user); // { name: "かつコーチ" }
配列で delete を使うと「空の穴」が残る問題がありましたが、オブジェクトの場合は delete でプロパティ自体をきれいに取り除けます。
つまずきやすいポイント:オブジェクトの比較
見た目が同じでも「別物」と判定される話
私がオブジェクトを学び始めたころ、一番混乱したのが オブジェクト同士の比較 でした。
❌ Before:=== で中身を比較しようとする
const userA = { name: "かつコーチ", age: 30 };
const userB = { name: "かつコーチ", age: 30 };
console.log(userA === userB); // false(中身は同じなのに…)
中身が完全に同じでも、userA と userB は 別々に作られたオブジェクト(別の参照) なので、=== で比較すると false になります。
数値や文字列の比較と同じ感覚で === を使ってしまい、「なぜ同じ内容なのにfalseになるんだ」としばらく悩んだのを覚えています。
✅ After:中身を比較したいときは、キーごとに比較するかJSON化して比較する
const userA = { name: "かつコーチ", age: 30 };
const userB = { name: "かつコーチ", age: 30 };
// シンプルな方法:JSON文字列に変換してから比較する
console.log(JSON.stringify(userA) === JSON.stringify(userB)); // true
// 同じオブジェクトを参照している場合はtrueになる
const userC = userA;
console.log(userA === userC); // true(同じ参照)
「=== はあくまで参照(同じ実体かどうか)を比較するもので、オブジェクトの中身の一致を保証するものではない」と理解しておくと、この落とし穴を避けられます。
(JSON.stringify によるオブジェクトの比較はキーの順序に影響される簡易的な方法のため、厳密な比較が必要な場合は専用のライブラリを使うこともあります。)
応用:分割代入とスプレッド構文
分割代入でプロパティを取り出す
オブジェクトから複数のプロパティを取り出したいとき、毎回 object.name のように書くのは冗長です。
分割代入(Destructuring) を使うと、必要なプロパティだけをまとめて変数に取り出せます。
const user = {
name: "かつコーチ",
age: 30,
email: "example@example.com",
};
const { name, age } = user;
console.log(name); // かつコーチ
console.log(age); // 30
関数の引数にオブジェクトを渡すときにも分割代入はよく使われます。
function showProfile({ name, age }) {
console.log(`${name}さん(${age}歳)`);
}
showProfile(user); // かつコーチさん(30歳)
スプレッド構文でオブジェクトをコピー・結合する
配列と同様に、オブジェクトもそのまま代入すると同じ実体を参照してしまいます。
安全にコピーしたいときは、スプレッド構文(...)を使います。
const user = { name: "かつコーチ", age: 30 };
// コピーしつつ、一部のプロパティだけ上書きする
const updatedUser = { ...user, age: 31 };
console.log(user); // { name: "かつコーチ", age: 30 }(元は変わらない)
console.log(updatedUser); // { name: "かつコーチ", age: 31 }
「元のオブジェクトを直接書き換えず、変更後の新しいオブジェクトを作る」という考え方は、特にReactなどのフレームワークを学ぶ際にも頻繁に登場する重要な考え方なので、ここで慣れておくとあとが楽になります。
まとめ
この記事のポイント
- オブジェクトは「キー」と「値」のセットでデータを管理する入れ物
- 値へのアクセスは基本的にドット記法、キーが変数の場合はブラケット記法を使う
constでもプロパティの追加・更新・削除はできる(再代入だけが禁止される)===はオブジェクトの中身ではなく参照を比較するため、中身が同じでもfalseになることがある- 分割代入・スプレッド構文を使うと、プロパティの取り出しやコピーがすっきり書ける
次に読むべき記事
オブジェクトの基本が分かったら、次は処理をまとめて再利用できる「関数」について学んでいきましょう。
→ 次の記事:関数の作り方と引数・戻り値