JavaScriptのプロパティ完全ガイド|基本から応用まで徹底解説

目次

1. はじめに

JavaScriptは、Web開発において最も広く使用されているプログラミング言語の一つです。特に、JavaScriptの「オブジェクト」と「プロパティ」は、データを管理し、操作する上で不可欠な概念です。

本記事では、JavaScriptのプロパティについて初心者にも分かりやすく解説します。
プロパティとは何か、どのように操作するのか、どんな種類があるのかを詳しく説明し、実際のコード例を交えながら理解を深めていきます。

2. JavaScriptのプロパティとは?基本の概念を解説

JavaScriptのオブジェクトは、「キー」と「値」のペア でデータを管理します。この「キー」に紐づいた値をプロパティ(property)と呼びます。

2.1 プロパティの基本構造

JavaScriptのオブジェクトは、波括弧 {} を使って作成され、キーと値のペアを持ちます。以下のように記述します。

const person = {
  name: "佐藤",
  age: 25,
  job: "エンジニア"
};

この例では、nameagejobがプロパティです。person.nameperson["age"] という形で値を取得できます。

2.2 プロパティの種類

JavaScriptのプロパティには、大きく分けて「データプロパティ」「アクセサプロパティ」の2種類があります。

  • データプロパティ
    → 値を直接保持するプロパティ
  • アクセサプロパティ
    gettersetter を使って値を取得・設定するプロパティ

この違いについては、後のセクションで詳しく解説します。

2.3 JavaScriptのプロパティの役割

プロパティを適切に管理することで、オブジェクトのデータ構造を整理し、コードの可読性や再利用性を向上させることができます。

3. JavaScriptのプロパティの属性とは?writableenumerableconfigurableを解説

JavaScriptのプロパティは、単なる「キーと値」のペアではなく、特定の属性(プロパティディスクリプタ)を持っています。
この属性を理解することで、プロパティの挙動を細かく制御できるようになります。

3.1 プロパティの属性とは?

JavaScriptのプロパティには、以下の3つの主要な属性があります。

属性名説明
writable値の変更を許可するかどうか(true / false
enumerableプロパティが列挙(ループで取得)できるかどうか
configurableプロパティの削除や属性変更を許可するかどうか

デフォルトでは、これらの属性はすべて true に設定されています。しかし、Object.defineProperty() を使うことで、細かく制御できます。

3.2 Object.defineProperty() でプロパティの属性を設定する

プロパティの属性を変更するには、Object.defineProperty() メソッドを使用します。
このメソッドは、オブジェクトのプロパティに対して詳細な設定を適用できます。

const user = {};

// プロパティ 'name' を定義
Object.defineProperty(user, "name", {
  value: "田中",
  writable: false,   // 値の変更を禁止
  enumerable: true,  // for...in で取得可能
  configurable: false // 削除や再設定を禁止
});

console.log(user.name); // "田中"

user.name = "佐藤"; // エラー(writable: false のため)

3.3 writable の詳細

writable は、プロパティの値を変更できるかどうかを制御します。

const obj = {};
Object.defineProperty(obj, "message", {
  value: "変更不可のメッセージ",
  writable: false
});

console.log(obj.message); // "変更不可のメッセージ"
obj.message = "新しいメッセージ"; // エラー

writable: false を設定すると、値を変更できなくなります。

3.4 enumerable の詳細

enumerable は、プロパティが for...inObject.keys() で取得されるかどうかを制御します。

const obj = {};
Object.defineProperty(obj, "hidden", {
  value: "これは隠しプロパティ",
  enumerable: false
});

console.log(Object.keys(obj)); // [] (hiddenは取得されない)
for (let key in obj) {
  console.log(key); // 出力なし
}

enumerable: false にすると、ループで取得できなくなります。
しかし、Object.getOwnPropertyNames(obj) を使えば取得できます。

console.log(Object.getOwnPropertyNames(obj)); // ["hidden"]

3.5 configurable の詳細

configurable は、プロパティの削除や再定義を許可するかどうかを決定します。

const obj = {};
Object.defineProperty(obj, "immutable", {
  value: "削除できないプロパティ",
  configurable: false
});

delete obj.immutable; // 削除できない
console.log(obj.immutable); // "削除できないプロパティ"

configurable: false にすると、delete で削除できなくなります。
また、一度 configurable: false を設定すると、後から変更することもできません。

3.6 まとめ

  • writable → 値の変更を許可するかどうか
  • enumerable → ループで取得可能かどうか
  • configurable → 削除や属性の変更が可能かどうか

Object.defineProperty() を使えば、これらの属性を細かく制御できるようになります。

4. JavaScriptのプロパティの追加・変更・削除の方法【サンプルコード付き】

JavaScriptでは、オブジェクトのプロパティを簡単に追加・変更・削除することができます。
このセクションでは、基本的なプロパティの操作方法を解説し、Object.defineProperty() を使った制御方法も紹介します。

4.1 プロパティの追加方法

オブジェクトのプロパティは、ドット記法またはブラケット記法を使って追加できます。

const user = {};

// プロパティの追加
user.name = "佐藤";
user["age"] = 30;

console.log(user); // { name: "佐藤", age: 30 }

どちらの記法を使うべき?

  • ドット記法(obj.key = value → シンプルで可読性が高い
  • ブラケット記法(obj["key"] = value → 変数をキーとして使用する場合に便利
const key = "email";
user[key] = "sato@example.com";
console.log(user.email); // "sato@example.com"

4.2 プロパティの変更方法

既存のプロパティの値は、単純に代入すれば変更できます。

const user = {
  name: "佐藤",
  age: 30
};

// プロパティの値を変更
user.age = 31;
console.log(user.age); // 31

ただし、writable: false のプロパティは変更できません。

const user = {};
Object.defineProperty(user, "id", {
  value: 12345,
  writable: false
});

user.id = 67890; // エラー
console.log(user.id); // 12345

4.3 プロパティの削除方法

オブジェクトのプロパティを削除するには、delete 演算子を使用します。

const user = {
  name: "佐藤",
  age: 30
};

// プロパティを削除
delete user.age;

console.log(user); // { name: "佐藤" }
console.log(user.age); // undefined

ただし、configurable: false に設定されたプロパティは削除できません。

const user = {};
Object.defineProperty(user, "role", {
  value: "admin",
  configurable: false
});

delete user.role; // 削除できない
console.log(user.role); // "admin"

4.4 Object.defineProperty() を使ったプロパティの制御

Object.defineProperty() を使用すると、プロパティの追加や変更をより厳密に管理できます。

const user = {};

Object.defineProperty(user, "username", {
  value: "sato123",
  writable: true,   // 変更可能
  enumerable: true, // ループで取得可能
  configurable: true // 削除可能
});

console.log(user.username); // "sato123"

特定のルールを持たせたい場合は、defineProperty を活用すると便利です。

4.5 まとめ

  • プロパティの追加obj.key = value または obj["key"] = value
  • プロパティの変更obj.key = newValue で変更(writable: false の場合は不可)
  • プロパティの削除delete obj.key で削除(configurable: false の場合は不可)
  • Object.defineProperty() を使うと制御が可能

5. アクセサプロパティ(getterとsetter)の活用方法

これまでのセクションでは、JavaScriptのプロパティの基本や属性について解説しました。
ここでは、アクセサプロパティ(getter と setter) について詳しく見ていきます。

アクセサプロパティを活用することで、プロパティの取得や設定時に特定の処理を実行できるようになります。

5.1 アクセサプロパティとは?

JavaScriptのプロパティには、以下の2種類があります。

プロパティの種類説明
データプロパティ値を直接保持するプロパティ
アクセサプロパティgettersetter を使って動的な処理を適用

アクセサプロパティを使うことで、データの取得時や設定時に追加の処理を実行できます。

5.2 getter を使って値を取得する

getter を定義すると、プロパティの値を取得する際に関数を実行 できます。

const user = {
  firstName: "太郎",
  lastName: "佐藤",

  // getter の定義
  get fullName() {
    return `${this.lastName} ${this.firstName}`;
  }
};

console.log(user.fullName); // "佐藤 太郎"

5.3 setter を使って値を設定する

setter を定義すると、プロパティの値を設定する際に関数を実行 できます。

const user = {
  firstName: "太郎",
  lastName: "佐藤",

  // setter の定義
  set fullName(value) {
    const parts = value.split(" ");
    this.lastName = parts[0];
    this.firstName = parts[1];
  }
};

// setter を使って値を変更
user.fullName = "田中 一郎";

console.log(user.firstName); // "一郎"
console.log(user.lastName); // "田中"

5.4 gettersetter の組み合わせ

gettersetter を組み合わせることで、データの取得と設定をより柔軟に制御できます。

const product = {
  _price: 1000, // プライベートな変数(慣習的に "_" を付ける)

  get price() {
    return `${this._price} 円`;
  },

  set price(value) {
    if (value < 0) {
      console.error("価格は0以上でなければなりません");
    } else {
      this._price = value;
    }
  }
};

// price の取得
console.log(product.price); // "1000 円"

// price の設定
product.price = 1500;
console.log(product.price); // "1500 円"

// 無効な値を設定
product.price = -500; // エラー: 価格は0以上でなければなりません

5.5 Object.defineProperty() を使って getter / setter を定義する

Object.defineProperty() を使っても、getter / setter を定義できます。

const user = {};
Object.defineProperty(user, "fullName", {
  get() {
    return this.firstName + " " + this.lastName;
  },
  set(value) {
    const parts = value.split(" ");
    this.firstName = parts[0];
    this.lastName = parts[1];
  }
});

user.firstName = "花子";
user.lastName = "鈴木";
console.log(user.fullName); // "花子 鈴木"

user.fullName = "山田 次郎";
console.log(user.firstName); // "山田"
console.log(user.lastName); // "次郎"

5.6 アクセサプロパティの活用例

アクセサプロパティは、以下のような場面で特に有効です。

使用シーン
データのフォーマット変換金額の表示を「〇〇円」に統一
バリデーションの適用価格がマイナスにならないように制限
計算プロパティの作成fullName を動的に生成
APIデータの変換JSONデータをオブジェクトに変換

例えば、ユーザーの誕生日を設定し、それを年齢として計算することも可能です。

const user = {
  birthYear: 2000,

  get age() {
    return new Date().getFullYear() - this.birthYear;
  }
};

console.log(user.age); // 今年の西暦から2000を引いた値が出力される

5.7 まとめ

  • getter → プロパティの取得時に処理を実行する
  • setter → プロパティの設定時に処理を実行する
  • バリデーションやフォーマット変換に役立つ
  • Object.defineProperty() を使って getter / setter を定義可能

アクセサプロパティを適切に活用すると、オブジェクトのデータ管理がより柔軟になります。

6. JavaScriptのプロパティを列挙する方法【for...inObject.keys()の違い】

JavaScriptのオブジェクトには複数のプロパティが存在しますが、それらを一覧で取得したい場面も多いでしょう。本セクションでは、オブジェクトのプロパティを列挙する方法 について解説し、for...inObject.keys()Object.getOwnPropertyNames() の違いを詳しく説明します。

6.1 オブジェクトのプロパティを列挙するとは?

「プロパティを列挙する」 とは、オブジェクトに含まれるキーを取得することを指します。例えば、以下のオブジェクトに対して、すべてのプロパティを取得する方法を考えます。

const user = {
  name: "佐藤",
  age: 30,
  job: "エンジニア"
};

このオブジェクトのすべてのキー(nameagejob)を取得する方法として、以下の3つがよく使われます。

  1. for...in ループ
  2. Object.keys()
  3. Object.getOwnPropertyNames()

それぞれの違いを詳しく見ていきましょう。

6.2 for...in を使ってプロパティを列挙する

for...in ループを使うと、オブジェクトのすべての列挙可能なプロパティ を取得できます。

const user = {
  name: "佐藤",
  age: 30,
  job: "エンジニア"
};

for (let key in user) {
  console.log(key); // "name", "age", "job"
}

for...in の特徴

オブジェクトのすべての列挙可能なプロパティを取得できる
プロトタイプチェーン上のプロパティも取得してしまう
属性 enumerable: false のプロパティは取得できない

例えば、プロトタイプにプロパティを追加すると、for...in にも表示されてしまいます。

const user = {
  name: "佐藤",
  age: 30
};

// プロトタイプにプロパティを追加
Object.prototype.role = "一般ユーザー";

for (let key in user) {
  console.log(key); // "name", "age", "role"(意図しないプロパティが取得される)
}

6.3 Object.keys() を使ってプロパティを取得する

Object.keys() を使うと、オブジェクトの自身が持つ列挙可能なプロパティのみを配列として取得 できます。

const user = {
  name: "佐藤",
  age: 30,
  job: "エンジニア"
};

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

Object.keys() の特徴

自身が持つプロパティのみ取得できる(プロトタイプのプロパティは取得しない)
enumerable: false のプロパティは取得できない
戻り値は配列なので、配列メソッド(map()filter())と組み合わせられる

例えば、forEach() を使ってプロパティを順番に処理することも可能です。

Object.keys(user).forEach(key => {
  console.log(`${key}: ${user[key]}`);
});

6.4 Object.getOwnPropertyNames() を使ってすべてのプロパティを取得する

Object.getOwnPropertyNames() を使うと、オブジェクトのすべての自身のプロパティ(enumerable: false のものも含む) を取得できます。

const user = {};
Object.defineProperty(user, "id", {
  value: 12345,
  enumerable: false
});

console.log(Object.getOwnPropertyNames(user)); // ["id"]

Object.getOwnPropertyNames() の特徴

enumerable: false のプロパティも取得できる
自身が持つプロパティのみ取得できる(プロトタイプは取得しない)
特殊なプロパティ(システム用のもの)も取得可能

6.5 どの方法を使うべきか?

方法プロトタイプを取得enumerable: false を取得戻り値
for...in取得する取得しない文字列(ループ)
Object.keys()取得しない取得しない配列
Object.getOwnPropertyNames()取得しない取得する配列

状況ごとの選び方

使用シーン適切な方法
通常のプロパティを列挙したいObject.keys()
enumerable: false のプロパティも含めたいObject.getOwnPropertyNames()
すべてのプロパティをループ処理したいfor...in(ただし hasOwnProperty() を併用)

💡 for...in を使う場合は hasOwnProperty() を併用すると安全

for (let key in user) {
  if (user.hasOwnProperty(key)) {
    console.log(key);
  }
}

6.6 まとめ

  • for...inプロトタイプも含めた列挙可能なプロパティを取得する(推奨されない場合がある)
  • Object.keys()オブジェクトの自身の列挙可能なプロパティを取得する(最も一般的)
  • Object.getOwnPropertyNames()enumerable: false のプロパティも取得する(システム用途)

7. まとめ【JavaScriptのプロパティの総復習とベストプラクティス】

ここまで、JavaScriptのプロパティについて基本から応用まで詳しく解説してきました。
このセクションでは、これまで学んだポイントを振り返り、実践で役立つベストプラクティス を紹介します。

7.1 JavaScriptのプロパティの総復習

トピックポイント
プロパティとは?オブジェクトのキーと値のペア
データプロパティ通常のプロパティ(値を直接保持)
アクセサプロパティgetter / setter を使って動的な処理を適用
プロパティの属性writableenumerableconfigurable
プロパティの追加・変更・削除=delete を使う
Object.defineProperty() の活用プロパティの属性を細かく設定可能
プロパティの列挙for...inObject.keys()Object.getOwnPropertyNames()

7.2 JavaScriptのプロパティを扱う際のベストプラクティス

1. 変更禁止のプロパティには writable: false を設定する
特定のプロパティの変更を禁止したい場合は、Object.defineProperty() を使う。

const user = {};
Object.defineProperty(user, "id", {
  value: 1001,
  writable: false
});

user.id = 2002; // エラー(変更不可)

2. ループでプロパティを列挙する際は Object.keys() を使う
for...in はプロトタイプのプロパティも取得してしまうため、Object.keys() を推奨。

const user = { name: "佐藤", age: 30 };
console.log(Object.keys(user)); // ["name", "age"]

3. getter / setter を使ってデータのフォーマットやバリデーションを適用する
アクセサプロパティを活用すると、データの整合性を維持できる。

const product = {
  _price: 1000,
  get price() {
    return `${this._price} 円`;
  },
  set price(value) {
    if (value < 0) {
      console.error("価格は0以上でなければなりません");
    } else {
      this._price = value;
    }
  }
};

product.price = -500; // エラー発生

4. Object.freeze()Object.seal() を使ってオブジェクトの変更を制限する
オブジェクト全体の変更を禁止したい場合は Object.freeze()、プロパティの追加・削除のみを禁止したい場合は Object.seal() を使う。

const user = { name: "佐藤" };
Object.freeze(user);

user.name = "田中"; // エラー(変更不可)
delete user.name;   // エラー(削除不可)

5. プロパティを列挙する際は Object.hasOwnProperty() を併用する
プロトタイプの影響を排除するために hasOwnProperty() を使うと安全。

for (let key in user) {
  if (user.hasOwnProperty(key)) {
    console.log(key);
  }
}

7.3 まとめ

✅ JavaScriptのプロパティを適切に管理することで、より安全で効率的なコードを作成できる!

  • データの変更を制御 したい場合は、Object.defineProperty()Object.freeze() を活用する
  • プロパティの列挙Object.keys() を使い、for...in を使う場合は hasOwnProperty() でフィルタリング
  • アクセサプロパティ を活用すると、データの整合性を保つことができる

これらのベストプラクティスを意識することで、より保守性の高いコードを書くことができます。

8. FAQ(よくある質問)

JavaScriptのプロパティに関するよくある疑問について、詳しく解説します。
初心者がつまずきやすいポイントや実践的な疑問をまとめたので、ぜひ参考にしてください。

8.1 hasOwnProperty()in 演算子の違いは何ですか?

A:

  • hasOwnProperty() は、オブジェクトの 自身のプロパティ のみをチェックします。
  • in 演算子は、オブジェクトの プロトタイプチェーン上のプロパティも含めて チェックします。
const obj = { name: "佐藤" };
console.log(obj.hasOwnProperty("name")); // true
console.log("name" in obj); // true

console.log(obj.hasOwnProperty("toString")); // false(プロトタイプのプロパティ)
console.log("toString" in obj); // true(プロトタイプに存在)

8.2 Object.defineProperty() の利点は何ですか?

A:
Object.defineProperty() を使うと、プロパティの属性を細かく制御できる ため、通常の = を使ったプロパティの定義よりも強力です。

const user = {};
Object.defineProperty(user, "id", {
  value: 12345,
  writable: false, // 変更不可
  enumerable: false, // ループで取得不可
  configurable: false // 削除不可
});

console.log(user.id); // 12345
user.id = 67890; // エラー(変更できない)
console.log(Object.keys(user)); // [](非列挙のため取得不可)

8.3 アクセサプロパティ(getter と setter)はどんな場面で使うべき?

A:
gettersetter は、プロパティの取得・設定時に処理を加えたい場合 に使用します。

const product = {
  _price: 1000,

  get price() {
    return `${this._price} 円`;
  },

  set price(value) {
    if (value < 0) {
      console.error("価格は0以上でなければなりません");
    } else {
      this._price = value;
    }
  }
};

console.log(product.price); // "1000 円"
product.price = -500; // エラー発生

8.4 プロパティの変更を禁止したい場合はどうすればいい?

A:
オブジェクトのプロパティの変更を防ぐ方法は複数あります。

const user = { name: "佐藤" };
Object.freeze(user);

user.name = "田中"; // エラー(変更不可)
delete user.name;   // エラー(削除不可)

8.5 for...inObject.keys() はどちらを使うべき?

A:

  • for...inプロトタイプのプロパティも含めて 取得してしまうため、慎重に使う必要がある。
  • Object.keys()オブジェクト自身が持つ列挙可能なプロパティのみ取得 するため、安全性が高い。
const user = { name: "佐藤", age: 30 };

for (let key in user) {
  console.log(key); // "name", "age"
}

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

8.6 まとめ

  • hasOwnProperty() を使うとプロトタイプのプロパティを無視できる
  • Object.defineProperty() でプロパティの動作を細かく制御可能
  • アクセサプロパティ(getter / setter) はデータの整形やバリデーションに便利
  • Object.freeze() を使うとオブジェクトの変更を完全に禁止できる
  • プロパティの列挙には Object.keys() を使うのが安全

これで、JavaScriptのプロパティに関する知識をしっかりと身につけることができました!
今回の解説を参考に、実際のコーディングに活かしてください。

広告