1. はじめに
JavaScriptは、Web開発において最も広く使用されているプログラミング言語の一つです。特に、JavaScriptの「オブジェクト」と「プロパティ」は、データを管理し、操作する上で不可欠な概念です。
本記事では、JavaScriptのプロパティについて初心者にも分かりやすく解説します。
プロパティとは何か、どのように操作するのか、どんな種類があるのかを詳しく説明し、実際のコード例を交えながら理解を深めていきます。
2. JavaScriptのプロパティとは?基本の概念を解説
JavaScriptのオブジェクトは、「キー」と「値」のペア でデータを管理します。この「キー」に紐づいた値をプロパティ(property)と呼びます。
2.1 プロパティの基本構造
JavaScriptのオブジェクトは、波括弧 {}
を使って作成され、キーと値のペアを持ちます。以下のように記述します。
const person = {
name: "佐藤",
age: 25,
job: "エンジニア"
};
この例では、name
、age
、job
がプロパティです。person.name
や person["age"]
という形で値を取得できます。
2.2 プロパティの種類
JavaScriptのプロパティには、大きく分けて「データプロパティ」と「アクセサプロパティ」の2種類があります。
- データプロパティ
→ 値を直接保持するプロパティ - アクセサプロパティ
→getter
やsetter
を使って値を取得・設定するプロパティ
この違いについては、後のセクションで詳しく解説します。
2.3 JavaScriptのプロパティの役割
プロパティを適切に管理することで、オブジェクトのデータ構造を整理し、コードの可読性や再利用性を向上させることができます。
3. JavaScriptのプロパティの属性とは?writable
・enumerable
・configurable
を解説
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...in
や Object.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種類があります。
プロパティの種類 | 説明 |
---|---|
データプロパティ | 値を直接保持するプロパティ |
アクセサプロパティ | getter と setter を使って動的な処理を適用 |
アクセサプロパティを使うことで、データの取得時や設定時に追加の処理を実行できます。
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 getter
と setter
の組み合わせ
getter
と setter
を組み合わせることで、データの取得と設定をより柔軟に制御できます。
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...in
とObject.keys()
の違い】
JavaScriptのオブジェクトには複数のプロパティが存在しますが、それらを一覧で取得したい場面も多いでしょう。本セクションでは、オブジェクトのプロパティを列挙する方法 について解説し、for...in
、Object.keys()
、Object.getOwnPropertyNames()
の違いを詳しく説明します。
6.1 オブジェクトのプロパティを列挙するとは?
「プロパティを列挙する」 とは、オブジェクトに含まれるキーを取得することを指します。例えば、以下のオブジェクトに対して、すべてのプロパティを取得する方法を考えます。
const user = {
name: "佐藤",
age: 30,
job: "エンジニア"
};
このオブジェクトのすべてのキー(name
、age
、job
)を取得する方法として、以下の3つがよく使われます。
for...in
ループObject.keys()
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 を使って動的な処理を適用 |
プロパティの属性 | writable 、enumerable 、configurable |
プロパティの追加・変更・削除 | = や delete を使う |
Object.defineProperty() の活用 | プロパティの属性を細かく設定可能 |
プロパティの列挙 | for...in 、Object.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:getter
と setter
は、プロパティの取得・設定時に処理を加えたい場合 に使用します。
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...in
と Object.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のプロパティに関する知識をしっかりと身につけることができました!
今回の解説を参考に、実際のコーディングに活かしてください。