JavaScript 入門

JS オブジェクトプロパティのアクセス

前の章では、JavaScriptにおけるオブジェクトの基本概念について学びました。オブジェクトを使用することで、現実世界のエンティティのように、関連するデータと機能を意味のある一つのユニットとしてまとめることができます。

オブジェクトは、コードを整理し、複雑な情報を構造化された形で表現するのに非常に強力です。しかし、オブジェクトを作成することは最初の一歩に過ぎません。オブジェクトの真の力を引き出すには、オブジェクトが保持している個々のデータ、すなわち プロパティ (Properties) へのアクセス方法を知る必要があります。

本章では、オブジェクトのプロパティにアクセスするための2つの主要な手法、ドット記法 (Dot Notation)ブラケット記法 (Bracket Notation) について深く掘り下げ、それぞれの使用シーンと理由を理解していきます。

1. オブジェクトプロパティへのアクセス:基礎知識

様々なプロパティを含むオブジェクトを作成した後は、それらのプロパティに関連付けられた値を読み取(取得)る必要が出てきます。

オブジェクトは、ラベルが貼られた 「箱」 のようなものだと想像してください。その中には、さらに小さなラベル付きの仕切り(プロパティ)があり、それぞれの仕切りに特定のアイテム(値)が入っています。プロパティにアクセスするということは、メインの箱を開け、ラベルを頼りに正しい仕切りを見つけ、中のアイテムを取り出すことを意味します。

JavaScriptでは、オブジェクトの内部を見てプロパティの値を取得するための主要な方法が2つ提供されています:

  • ドット記法 (Dot Notation, .): 最も一般的で、通常はこちらが推奨される方法です。
  • ブラケット記法 (Bracket Notation, []): より柔軟性が高く、特にプロパティ名が標準的でない場合や動的に決定される場合に必要となります。

これら両方の手法を使用して、プロパティの値を読み取ったり、既存のプロパティに新しい値を代入したり、オブジェクトの作成後に新しいプロパティを追加したりすることができます。

1.1 サンプルオブジェクトの作成

本セクションでは、ドット記法とブラケット記法の動作をデモンストレーションするために、person(人)オブジェクトをメインの例として使用します。

// サンプルの 'person' オブジェクト
let person = {
  firstName: "アリス",
  lastName: "スミス",
  age: 30,
  "eye color": "ブルー", // スペースを含むプロパティ名
  isStudent: false,
  hobbies: ["読書", "ハイキング", "コーディング"], // 配列を値に持つ
  address: { // ネストされたオブジェクトを値に持つ
    street: "メインストリート 123",
    city: "ニューヨーク",
    zipCode: "10001"
  }
};

console.log(person);
/* 出力:
{
  firstName: 'アリス',
  lastName: 'スミス',
  age: 30,
  'eye color': 'ブルー',
  isStudent: false,
  hobbies: [ '読書', 'ハイキング', 'コーディング' ],
  address: { street: 'メインストリート 123', city: 'ニューヨーク', zipCode: '10001' }
}
*/

2. ドット記法 (Dot Notation, .)

ドット記法は、オブジェクトのプロパティにアクセスするための最もシンプルで一般的な方法です。簡潔で読みやすいため、ほとんどのケースでデフォルトの選択肢となります。

2.1 ドット記法の仕組み

ドット記法を使用するには、オブジェクト名の後にドット(.)を書き、その後にアクセスしたいプロパティ名を記述します。

構文: objectName.propertyName

       注意:propertyName は有効な JavaScript 識別子 (Identifier) である必要があります。つまり、スペースやハイフンを含めることはできず、数字で始めることもできません。また、JavaScriptの予約語(ifforfunction など)も使用できません。

2.2 ドット記法の使用例

2.2.1 プロパティ値の取得

let person = {
  firstName: "アリス",
  lastName: "スミス",
  age: 30,
  isStudent: false
};

// ドット記法を使用してプロパティにアクセス
let personFirstName = person.firstName;
console.log("名前:", personFirstName); // 出力: 名前: アリス

let personAge = person.age;
console.log("年齢:", personAge); // 出力: 年齢: 30

console.log("学生ですか:", person.isStudent); // 出力: 学生ですか: false

2.2.2 ネストされたオブジェクトのプロパティへのアクセス

オブジェクトのプロパティ値が別のオブジェクトである場合、ドット記法を チェーン(連鎖) させることで、ネストされたオブジェクト内のプロパティにアクセスできます。これにより、複雑なデータ構造の深部まで探索することが可能です。

let person = {
  firstName: "アリス",
  lastName: "スミス",
  address: { // ネストされたオブジェクト
    street: "メインストリート 123",
    city: "ニューヨーク",
    zipCode: "10001"
  }
};

// ネストされたプロパティにアクセス
console.log("通り:", person.address.street);     // 出力: 通り: メインストリート 123
console.log("都市:", person.address.city);       // 出力: 都市: ニューヨーク
console.log("郵便番号:", person.address.zipCode); // 出力: 郵便番号: 10001

2.2.3 既存のプロパティ値の変更

ドット記法と代入演算子(=)を組み合わせることで、既存のプロパティ値を変更できます。

let person = {
  firstName: "アリス",
  lastName: "スミス",
  age: 30
};

console.log("元の年齢:", person.age); // 出力: 元の年齢: 30

// 'age' プロパティの値を変更
person.age = 31;
console.log("新しい年齢:", person.age); // 出力: 新しい年齢: 31

// 'firstName' プロパティの値を変更
person.firstName = "アリシア";
console.log("新しい名前:", person.firstName); // 出力: 新しい名前: アリシア

2.2.4 新しいプロパティの追加

オブジェクトに存在しないプロパティ名に対して値を代入しようとすると、JavaScriptはその新しいプロパティを自動的に作成します。

let person = {
  firstName: "アリス",
  lastName: "スミス"
};

console.log(person); // 出力: { firstName: 'アリス', lastName: 'スミス' }

// 新しいプロパティ 'occupation'(職業)を追加
person.occupation = "ソフトウェアエンジニア";
console.log("職業:", person.occupation); // 出力: 職業: ソフトウェアエンジニア

// 別の新しいプロパティ 'email' を追加
person.email = "[email protected]";
console.log("メール:", person.email); // 出力: メール: [email protected]

console.log(person);
/* 出力:
{
  firstName: 'アリス',
  lastName: 'スミス',
  occupation: 'ソフトウェアエンジニア',
  email: '[email protected]'
}
*/

2.3 ドット記法の制限事項

ドット記法は大半のケースで機能しますが、以下のような制限があります:

  • 無効な識別子: プロパティ名が有効なJavaScript識別子でない場合(例:スペースやハイフンを含む、数字で始まるなど)、ドット記法は使用できません。
  • 動的なプロパティ名: プロパティ名が変数に格納されている場合や、実行時に決定する必要がある場合、ドット記法は使用できません。

これらのシナリオでは、ブラケット記法を使用する必要があります。

3. ブラケット記法 (Bracket Notation, [])

ブラケット記法は、特にドット記法が適用できない場合に、オブジェクトのプロパティにアクセスするためのより柔軟な方法を提供します。ブラケット(大括弧)の中に 文字列(または文字列として評価される式)を使用してプロパティ名を指定できます。

3.1 ブラケット記法の仕組み

ブラケット記法を使用するには、オブジェクト名の後にブラケット([])を書き、その中にプロパティ名を 文字列 として記述します。

構文: objectName["propertyName"]

       重要ポイント: ブラケット内のプロパティ名は文字列である必要があります。この文字列は、リテラル文字列(例: "age")でも、文字列値を保持する変数でも構いません。

3.2 ブラケット記法の使用例

3.2.1 標準的な名前での取得

ドット記法でアクセス可能なプロパティ名であっても、ブラケット記法を使用できます。動作は同じですが、少し記述が長くなります。

let person = {
  firstName: "アリス",
  lastName: "スミス",
  age: 30
};

// 文字列リテラルを用いたブラケット記法でのアクセス
let personFirstName = person["firstName"];
console.log("名前:", personFirstName); // 出力: 名前: アリス

let personAge = person["age"];
console.log("年齢:", personAge); // 出力: 年齢: 30

3.2.2 無効な識別子を持つプロパティへのアクセス

これがブラケット記法の本領発揮です。プロパティ名にスペースやハイフンが含まれている場合、あるいは数字で始まる場合は、ブラケット記法を 使わなければなりません

let product = {
  name: "ノートパソコン",
  price: 1200,
  "item category": "電子機器", // スペースを含む
  "product-id": "XYZ-789",    // ハイフンを含む
  "1_year_warranty": true     // 数字で始まる
};

// "item category" にドット記法を使うとエラーになります:
// console.log(product.item category); // SyntaxError (構文エラー)

// ブラケット記法を使用して正しくアクセス
console.log("カテゴリー:", product["item category"]);    // 出力: カテゴリー: 電子機器
console.log("製品ID:", product["product-id"]);        // 出力: 製品ID: XYZ-789
console.log("保証:", product["1_year_warranty"]);     // 出力: 保証: true

3.2.3 動的プロパティアクセス(変数の使用)

ブラケット記法の最も強力な機能は、変数 を使用してプロパティにアクセスできる点です。実行時まで正確なプロパティ名がわからない場合や、プロパティをループで回したい場合に非常に便利です。

let person = {
  firstName: "アリス",
  lastName: "スミス",
  age: 30
};

let propertyToAccess = "age";

// 変数を使用して 'age' プロパティに動的にアクセス
console.log("動的アクセス(年齢):", person[propertyToAccess]); // 出力: 30

propertyToAccess = "firstName";
console.log("動的アクセス(名前):", person[propertyToAccess]); // 出力: アリス

// 関数にオブジェクトとプロパティ名を渡す例
function getPropertyValue(obj, propName) {
  return obj[propName]; // 動的アクセスのため、ここではブラケット記法が必須
}

console.log("関数経由で名字を取得:", getPropertyValue(person, "lastName")); // 出力: スミス

3.2.4 ブラケット記法によるプロパティの変更と追加

ドット記法と同様に、ブラケット記法を代入演算子の左側に使うことで、プロパティの修正や追加が可能です。

let person = {
  firstName: "アリス",
  age: 30
};

// ブラケット記法で 'age' を修正
person["age"] = 31;
console.log("新しい年齢:", person.age); // 出力: 31

// 新しいプロパティ 'middle name' を追加(スペースがあるためブラケット必須)
person["middle name"] = "マリー";
console.log("ミドルネーム:", person["middle name"]); // 出力: マリー

let newPropertyKey = "email";
let newPropertyValue = "[email protected]";

// 変数を使用して動的に新しいプロパティを追加
person[newPropertyKey] = newPropertyValue;
console.log("メール:", person.email); // 出力: [email protected]

4. どちらの記法を使うべきか

どちらの記法を使うべきか判断するためのクイック・サマリーです:

特徴ドット記法 (.)ブラケット記法 ([])
一般的な用途最も一般的。標準的な名前のデフォルト選択肢。動的アクセス、特殊文字を含む名前に使用。
プロパティ名の形式有効なJS識別子である必要あり(スペース・ハイフン不可、数字開始不可)。あらゆる文字列が可能(スペース、ハイフン、数字含む)。
動的アクセス不可可能 (変数を使用できる)
読みやすさ簡潔で読みやすい。少し煩雑だが、特定のケースでは必須。

判断の目安:

  1. デフォルトはドット記法: プロパティ名があらかじめ分かっており、それが有効なJavaScript識別子である場合は、こちらを使用します。コードが綺麗で読みやすくなります。
  2. ブラケット記法を使うケース:
    • プロパティ名に特殊文字(スペース、ハイフンなど)が含まれる場合。
    • プロパティ名が変数に格納されており、動的にアクセスする必要がある場合。
    • プロパティ名が数値の場合(例:let obj = {100: "value"}; obj[100];)。

5. 実戦的な例とデモンストレーション

学んだ知識を組み合わせて、より複雑なデータ処理のシナリオを見ていきましょう。

5.1 例 1:在庫管理システム

let inventory = {
  "item101": {
    name: "ノートパソコン",
    quantity: 15,
    "unit price": 1200, // スペースあり
    tags: ["電子機器", "PC"]
  },
  "item102": {
    name: "マウス",
    quantity: 50,
    "unit price": 25,
    tags: ["電子機器", "周辺機器"]
  }
};

// 1. ドット記法で item101 の名前を取得(有効な識別子なので可能)
console.log("Item 101 名称:", inventory.item101.name); // 出力: ノートパソコン

// 2. スペースを含む単価を取得(ブラケット記法が必須)
console.log("Item 102 単価:", inventory.item102["unit price"]); // 出力: 25

// 3. 変数に基づいて動的にアイテムにアクセス
let itemId = "item101";
let key = "quantity";
console.log(`${itemId} の ${key}:`, inventory[itemId][key]); // 出力: item101 の quantity: 15

5.2 例 2:APIレスポンスデータの処理

Web APIから受け取るデータ(JSON)は、しばしば異なる命名規則が混在しています。

let apiResponse = {
  status: "success",
  data: {
    userId: "user_123",
    "last_login_date": "2023-10-26", // アンダースコア
    profile: {
      "full_name": "ジョン・ドウ",
      email: "[email protected]",
      "account-status": "active" // ハイフンあり(ブラケット必須)
    }
  }
};

// ドット記法でトップレベルのプロパティにアクセス
console.log("ステータス:", apiResponse.status); 

// ハイフンが含まれるプロパティへのアクセス
console.log("アカウント状態:", apiResponse.data.profile["account-status"]); 

// 複雑なネスト構造からのデータ取得
console.log("ユーザー名:", apiResponse.data.profile["full_name"]);

このAPIの例が示すように、外部データを扱う際には命名規則が混在することが多いため、ドット記法とブラケット記法の両方を使いこなすことが不可欠です。