- 1 1. はじめに
- 2 2. JavaScriptのプロパティとは?
- 3 3. プロパティの作成と基本操作
- 4 4. プロパティの詳細設定
- 5 5. アクセサプロパティ(getterとsetter)
- 6 6. プロトタイプチェーンとプロパティの継承
- 7 7. プロパティの列挙と反復処理
- 8 8. 高度なプロパティ操作
- 9 9. よくある間違いとベストプラクティス
- 10 10. FAQ(よくある質問)
1. はじめに
JavaScriptを使ってプログラミングをしていると、「プロパティ(property)」という言葉を頻繁に目にすることになります。プロパティは、オブジェクトのデータや状態を保持するための重要な概念です。本記事では、JavaScriptのプロパティについて基本から応用までを詳しく解説し、初心者から中級者まで理解できるように構成しています。
この記事を読むことで、以下のポイントが分かるようになります。
- JavaScriptにおけるプロパティの基本概念
- プロパティの作成・更新・削除方法
- アクセス方法(ドット記法・ブラケット記法)
- プロトタイプチェーンと継承の仕組み
- 高度なプロパティ管理方法(
Object.defineProperty()
など) - よくある間違いとベストプラクティスまで
では、まずJavaScriptのプロパティとは何かについて見ていきましょう。
2. JavaScriptのプロパティとは?
2.1 プロパティの定義と役割
JavaScriptにおいてプロパティとは、オブジェクトに紐づくデータのこと です。JavaScriptのオブジェクトは、キー(名前)と値のペアで構成されています。この キーがプロパティ名 であり、対応する 値がプロパティの値 となります。
例えば、以下のようなオブジェクトを考えてみましょう。
const person = {
name: "太郎",
age: 25,
job: "エンジニア"
};
この person
オブジェクトには、name
、age
、job
という 3つのプロパティ が含まれています。それぞれ、
name
の値は"太郎"
age
の値は25
job
の値は"エンジニア"
となっています。
2.2 オブジェクトとプロパティの関係
JavaScriptでは、オブジェクトはプロパティを保持することでデータの集合を表現します。オブジェクトを使用することで、関連する情報をひとまとめに管理できるため、データの構造化が容易になります。
例えば、同じ情報を変数で管理する場合とオブジェクトで管理する場合を比較してみましょう。
const name = "太郎";
const age = 25;
const job = "エンジニア";
// オブジェクトで管理
const person = {
name: "太郎",
age: 25,
job: "エンジニア"
};
このように、オブジェクトを使うことで、複数のデータを 一つの単位 として扱うことができ、管理がしやすくなります。
2.3 データプロパティとアクセサプロパティの違い
JavaScriptのプロパティには データプロパティ(data property) と アクセサプロパティ(accessor property) の2種類があります。
- データプロパティ: 値を直接保持する通常のプロパティ(例:
name: "太郎"
) - アクセサプロパティ:
getter
やsetter
を使って間接的に値を取得・設定するプロパティ
例えば、アクセサプロパティを使用すると、以下のように動的な値の取得や設定が可能になります。
const person = {
firstName: "太郎",
lastName: "山田",
get fullName() {
return this.lastName + " " + this.firstName;
}
};
console.log(person.fullName); // "山田 太郎"
このように、アクセサプロパティを使うことで、プロパティの値を計算したり、特定のルールを適用することができます。
3. プロパティの作成と基本操作
3.1 プロパティの作成
JavaScriptでプロパティを作成する方法は大きく分けて2つあります。
- オブジェクトリテラルを使う方法
const user = {
name: "花子",
age: 30
};
→ {}
(中括弧)を使ってオブジェクトを作成し、その中でプロパティを定義します。
Object.defineProperty()
を使う方法
const user = {};
Object.defineProperty(user, "name", {
value: "花子",
writable: true,
enumerable: true,
configurable: true
});
→ Object.defineProperty()
を使うと、プロパティの詳細な設定が可能になります。
3.2 プロパティへのアクセス方法
JavaScriptでは、プロパティにアクセスする方法として ドット記法 と ブラケット記法 の2つがあります。
const user = { name: "花子", age: 30 };
// ドット記法
console.log(user.name); // "花子"
// ブラケット記法
console.log(user["age"]); // 30
ドット記法 はシンプルで使いやすいですが、プロパティ名が動的な場合は ブラケット記法 を使う必要があります。
const key = "name";
console.log(user[key]); // "花子"(変数をプロパティ名に利用)
3.3 プロパティの更新・削除
既存のプロパティの値を更新するには、代入(=
) を使います。
user.age = 31;
console.log(user.age); // 31
プロパティを削除するには delete
を使います。
delete user.age;
console.log(user.age); // undefined(プロパティが削除された)
ただし、Object.defineProperty()
で configurable: false
に設定したプロパティは削除できません。
4. プロパティの詳細設定
4.1 Object.defineProperty()
を使ったプロパティの詳細設定
Object.defineProperty()
を使用すると、オブジェクトのプロパティを詳細に定義できます。
基本構文
Object.defineProperty(オブジェクト, "プロパティ名", {
属性1: 値,
属性2: 値,
...
});
例: プロパティの詳細設定
const user = {};
Object.defineProperty(user, "name", {
value: "花子",
writable: false, // 値の変更不可
enumerable: true, // 列挙可能
configurable: false // 削除不可
});
console.log(user.name); // "花子"
user.name = "太郎"; // writable: false のため変更不可
console.log(user.name); // "花子"
delete user.name; // configurable: false のため削除不可
console.log(user.name); // "花子"
4.2 プロパティの属性
JavaScriptのプロパティには、以下の 3つの主要な属性 があります。
属性 | 説明 | デフォルト値 |
---|---|---|
writable | 値を変更できるかどうか | true |
enumerable | for...in や Object.keys() で列挙できるか | true |
configurable | 削除や属性の変更ができるか | true |
1. writable
(値の変更可否)
const obj = {};
Object.defineProperty(obj, "age", {
value: 30,
writable: false
});
obj.age = 40; // 書き換え不可
console.log(obj.age); // 30
2. enumerable
(列挙の可否)
const obj = {};
Object.defineProperty(obj, "hiddenValue", {
value: "秘密",
enumerable: false
});
console.log(Object.keys(obj)); // [] (hiddenValue は表示されない)
for (let key in obj) {
console.log(key); // 何も表示されない
}
3. configurable
(削除・変更の可否)
const obj = {};
Object.defineProperty(obj, "id", {
value: 12345,
configurable: false
});
delete obj.id; // 削除不可
console.log(obj.id); // 12345
4.3 Object.defineProperties()
を使った複数プロパティの定義
Object.defineProperties()
を使うと、複数のプロパティを一括で設定 できます。
const user = {};
Object.defineProperties(user, {
name: {
value: "太郎",
writable: true,
enumerable: true,
configurable: true
},
age: {
value: 25,
writable: false, // 変更不可
enumerable: true,
configurable: true
},
password: {
value: "secret",
writable: true,
enumerable: false // for...in や Object.keys() で表示されない
}
});
console.log(user); // { name: "太郎", age: 25 }
console.log(Object.keys(user)); // ["name", "age"](password は表示されない)
4.4 Object.getOwnPropertyDescriptor()
でプロパティ属性を取得
const obj = { name: "太郎" };
Object.defineProperty(obj, "age", {
value: 30,
writable: false,
enumerable: true,
configurable: true
});
console.log(Object.getOwnPropertyDescriptor(obj, "age"));
出力
{
value: 30,
writable: false,
enumerable: true,
configurable: true
}
まとめ
Object.defineProperty()
を使うことで、プロパティの詳細な制御が可能writable
,enumerable
,configurable
の 3つの属性を理解 することで、安全なオブジェクト設計ができるObject.defineProperties()
を使うと、複数のプロパティを一括設定 できるObject.getOwnPropertyDescriptor()
で プロパティの属性を確認 できる
5. アクセサプロパティ(getterとsetter)
5.1 アクセサプロパティとは?
アクセサプロパティとは、オブジェクトのプロパティの値を直接保持するのではなく、値の取得(getter)や設定(setter)の際に処理を行う特殊なプロパティ です。
データプロパティとアクセサプロパティの違い
プロパティの種類 | 仕組み | 使用例 |
---|---|---|
データプロパティ | 直接値を保持する | obj.name = "太郎"; |
アクセサプロパティ | getter / setter を使い、値を取得・設定時に処理を実行 | console.log(obj.fullName); |
5.2 getter
(ゲッター)の使い方
getter は、オブジェクトのプロパティにアクセスした際に、値を動的に計算・取得 するためのメソッドです。
getter の基本構文
const obj = {
get プロパティ名() {
return 計算結果;
}
};
getter の使用例
const person = {
firstName: "太郎",
lastName: "山田",
get fullName() {
return this.lastName + " " + this.firstName;
}
};
console.log(person.fullName); // "山田 太郎"
5.3 setter
(セッター)の使い方
setter は、プロパティに値を代入した際に、値を変更する処理をカスタマイズ するためのメソッドです。
setter の基本構文
const obj = {
set プロパティ名(新しい値) {
// 値を設定する処理
}
};
setter の使用例
const person = {
firstName: "太郎",
lastName: "山田",
get fullName() {
return this.lastName + " " + this.firstName;
},
set fullName(value) {
const parts = value.split(" ");
this.lastName = parts[0];
this.firstName = parts[1];
}
};
person.fullName = "佐藤 一郎";
console.log(person.firstName); // "一郎"
console.log(person.lastName); // "佐藤"
console.log(person.fullName); // "佐藤 一郎"
5.4 Object.defineProperty()
を使った getter / setter の定義
Object.defineProperty()
を使うと、プロパティの属性を細かく設定しながら、getter / setter を定義できます。
例: Object.defineProperty()
を使った getter / setter
const user = { firstName: "花子", lastName: "田中" };
Object.defineProperty(user, "fullName", {
get() {
return this.lastName + " " + this.firstName;
},
set(value) {
const parts = value.split(" ");
this.lastName = parts[0];
this.firstName = parts[1];
},
enumerable: true,
configurable: true
});
console.log(user.fullName); // "田中 花子"
user.fullName = "佐藤 二郎";
console.log(user.fullName); // "佐藤 二郎"
console.log(user.firstName); // "二郎"
console.log(user.lastName); // "佐藤"
5.5 アクセサプロパティの活用例
1. データのフォーマット変換
const product = {
price: 1000,
get priceWithTax() {
return this.price * 1.1; // 消費税(10%)を適用
}
};
console.log(product.priceWithTax); // 1100
2. パスワードの安全な管理
const user = {
_password: "",
get password() {
return "****"; // パスワードの直接表示を防ぐ
},
set password(value) {
if (value.length >= 8) {
this._password = value;
} else {
console.log("パスワードは8文字以上である必要があります");
}
}
};
user.password = "short"; // "パスワードは8文字以上である必要があります"
user.password = "securePass123"; // 設定成功
console.log(user.password); // "****"
5.6 まとめ
- getter / setter を使うと、プロパティの取得・設定時に処理を挟むことができる
Object.defineProperty()
を使うと、詳細な制御が可能- データのフォーマット変換やパスワード管理など、実用的な用途が多い
- 頻繁に使用する場合は、パフォーマンスを考慮してキャッシュするのが望ましい

6. プロトタイプチェーンとプロパティの継承
6.1 プロトタイプチェーンとは?
JavaScriptのすべてのオブジェクトは、別のオブジェクトをプロトタイプ(親オブジェクト)として持つ ことができます。この仕組みをプロトタイプチェーン(prototype chain) と呼びます。
プロトタイプチェーンの基本
const obj = {}; // 空のオブジェクトを作成
console.log(obj.__proto__); // Object.prototype の参照
console.log(obj.__proto__.__proto__); // null(プロトタイプチェーンの終点)
オブジェクト obj
は、Object.prototype
をプロトタイプとして持っています。さらに Object.prototype
のプロトタイプは null
であり、ここがプロトタイプチェーンの終点 になります。
6.2 Object.getPrototypeOf()
を使ったプロトタイプの取得
オブジェクトのプロトタイプを取得するには、Object.getPrototypeOf()
を使用します。
使用例
const person = { name: "太郎" };
console.log(Object.getPrototypeOf(person)); // Object.prototype を参照
6.3 プロパティの継承と検索の仕組み
オブジェクトがプロパティを持たない場合、JavaScriptはプロトタイプチェーンをたどりながらプロパティを検索 します。
例: プロトタイプチェーンによるプロパティ検索
const parent = {
greet() {
return "こんにちは!";
}
};
const child = Object.create(parent); // 親オブジェクトを継承
console.log(child.greet()); // "こんにちは!"
プロパティの検索の流れ
child
にgreet
プロパティがあるか確認 → ないchild
のプロトタイプ(parent
)を調べる → あるparent.greet()
を呼び出して、"こんにちは!"
を出力
6.4 hasOwnProperty()
を使った自身のプロパティの確認
オブジェクト自身がプロパティを持っているかどうかを判別するには、hasOwnProperty()
を使います。
使用例
const parent = { greet: "こんにちは!" };
const child = Object.create(parent);
child.name = "太郎";
console.log(child.hasOwnProperty("name")); // true(自身のプロパティ)
console.log(child.hasOwnProperty("greet")); // false(継承されたプロパティ)
6.5 Object.create()
を使ったオブジェクトの継承
Object.create()
を使うと、任意のオブジェクトをプロトタイプとして持つ新しいオブジェクトを作成できます。
Object.create()
の基本
const animal = {
makeSound() {
return "鳴き声";
}
};
const dog = Object.create(animal);
console.log(dog.makeSound()); // "鳴き声"
6.6 class
を使ったプロトタイプの継承
ES6 以降では、class
構文を使うことで、より直感的にプロトタイプを継承できます。
class
を使った継承
class Animal {
constructor(name) {
this.name = name;
}
makeSound() {
return "鳴き声";
}
}
class Dog extends Animal {
bark() {
return "ワンワン!";
}
}
const dog = new Dog("ポチ");
console.log(dog.name); // "ポチ"
console.log(dog.makeSound()); // "鳴き声"(継承)
console.log(dog.bark()); // "ワンワン!"
6.7 プロトタイプ継承の注意点
- プロトタイプの変更は避ける
Object.setPrototypeOf()
や__proto__
を頻繁に変更すると、パフォーマンスが低下する。
- ループ処理で継承プロパティを除外
for...in
ループを使うと、継承されたプロパティも取得されるため、hasOwnProperty()
でフィルタリングするのが望ましい。
for (let key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // 自身のプロパティのみ表示
}
}
6.8 まとめ
- プロトタイプチェーンを理解することで、オブジェクトの継承を活用できる
Object.create()
を使うと、オブジェクトのプロトタイプを指定できるclass
構文を使うと、オブジェクト指向の設計がより直感的になるhasOwnProperty()
を使えば、オブジェクトのプロパティが継承されたものかどうかを判別可能- プロトタイプの変更はパフォーマンスに影響するため、慎重に行うことが重要
7. プロパティの列挙と反復処理
7.1 プロパティの列挙とは?
オブジェクトのプロパティを取得して処理すること を「プロパティの列挙」と言います。例えば、for...in
ループを使うと、オブジェクト内のすべてのプロパティを反復処理できます。
基本例: for...in
ループを使ったプロパティの列挙
const user = {
name: "太郎",
age: 25,
job: "エンジニア"
};
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
出力
name: 太郎
age: 25
job: エンジニア
7.2 プロパティの列挙方法と比較
メソッド | プロトタイプのプロパティ | シンボルプロパティ | 取得内容 |
---|---|---|---|
for...in | ✅ 含む | ❌ 含まない | 列挙可能なプロパティ(すべて) |
Object.keys() | ❌ 含まない | ❌ 含まない | 自身のプロパティのみ |
Object.values() | ❌ 含まない | ❌ 含まない | プロパティの値のみ |
Object.entries() | ❌ 含まない | ❌ 含まない | [キー, 値] のペア |
Object.getOwnPropertyNames() | ❌ 含まない | ❌ 含まない | enumerable: false のプロパティも取得 |
Object.getOwnPropertySymbols() | ❌ 含まない | ✅ 含む | シンボルプロパティのみ |
7.3 Object.keys()
を使ったプロパティの取得
特徴
- オブジェクトの「自身のプロパティのみ」取得
- プロトタイプのプロパティは含まれない
- 列挙可能なプロパティのみ取得
使用例
const user = {
name: "太郎",
age: 25
};
console.log(Object.keys(user)); // ["name", "age"]
7.4 Object.values()
を使った値の取得
特徴
- オブジェクトのプロパティの「値のみ」取得
- プロトタイプのプロパティは含まれない
使用例
const user = {
name: "太郎",
age: 25
};
console.log(Object.values(user)); // ["太郎", 25]
7.5 Object.entries()
を使ったキーと値の取得
特徴
[キー, 値]
のペアを配列として取得- プロトタイプのプロパティは含まれない
forEach()
などのメソッドと組み合わせやすい
使用例
const user = {
name: "太郎",
age: 25
};
console.log(Object.entries(user));
// [["name", "太郎"], ["age", 25]]
7.6 シンボルプロパティの列挙
通常の列挙メソッド (for...in
や Object.keys()
) は シンボル(Symbol
)のプロパティを取得しません。
シンボルプロパティを含める方法
const sym = Symbol("uniqueKey");
const obj = {
normalKey: "通常のキー",
[sym]: "シンボルの値"
};
console.log(Object.keys(obj)); // ["normalKey"](シンボルは取得されない)
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(uniqueKey)]
7.7 プロパティの列挙のベストプラクティス
- プロトタイプのプロパティを除外する場合は
Object.keys()
を使用
const keys = Object.keys(obj);
for...in
を使う場合はhasOwnProperty()
でフィルタリング
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
- シンボルプロパティを含める場合は
Object.getOwnPropertySymbols()
const symbols = Object.getOwnPropertySymbols(obj);
- 値が必要なら
Object.values()
やObject.entries()
を使用
Object.entries(obj).forEach(([key, value]) => {
console.log(key, value);
});
7.8 まとめ
for...in
は 継承プロパティを含む ため、hasOwnProperty()
を使ってフィルタリングするのがベスト。Object.keys()
は 自身のプロパティのみ取得 するので安全。Object.values()
は 値のみ を取得したい場合に便利。Object.entries()
は キーと値のペアを配列として取得 でき、データ操作しやすい。- シンボルプロパティを取得するには
Object.getOwnPropertySymbols()
を使用。
8. 高度なプロパティ操作
8.1 Object.defineProperties()
を使った複数プロパティの定義
Object.defineProperties()
を使うと、複数のプロパティを一度に定義 できます。
基本構文
Object.defineProperties(オブジェクト, {
プロパティ名1: { 設定1 },
プロパティ名2: { 設定2 },
});
使用例
const user = {};
Object.defineProperties(user, {
name: {
value: "太郎",
writable: true,
enumerable: true,
configurable: true
},
age: {
value: 25,
writable: false, // 変更不可
enumerable: true,
configurable: true
},
password: {
value: "secret",
writable: true,
enumerable: false // for...in や Object.keys() で表示されない
}
});
console.log(user); // { name: "太郎", age: 25 }
console.log(Object.keys(user)); // ["name", "age"](password は表示されない)
8.2 Object.getOwnPropertyDescriptors()
を使ったプロパティ情報の取得
Object.getOwnPropertyDescriptors()
を使うと、オブジェクト内のすべてのプロパティの詳細情報を取得 できます。
使用例
const user = {
name: "太郎",
age: 25
};
const descriptors = Object.getOwnPropertyDescriptors(user);
console.log(descriptors);
出力
{
name: {
value: "太郎",
writable: true,
enumerable: true,
configurable: true
},
age: {
value: 25,
writable: true,
enumerable: true,
configurable: true
}
}
8.3 Object.preventExtensions()
, Object.seal()
, Object.freeze()
を使ったオブジェクトの制限
JavaScriptでは、オブジェクトの変更を制限 するために以下の3つのメソッドが用意されています。
メソッド | 新しいプロパティ追加 | 既存プロパティ削除 | 既存プロパティ変更 |
---|---|---|---|
Object.preventExtensions() | ❌(追加不可) | ✅(削除可) | ✅(変更可) |
Object.seal() | ❌(追加不可) | ❌(削除不可) | ✅(変更可) |
Object.freeze() | ❌(追加不可) | ❌(削除不可) | ❌(変更不可) |
8.4 Object.assign()
と structuredClone()
によるプロパティのコピー
1. Object.assign()
(シャローコピー)
const user = { name: "太郎", age: 25 };
const copiedUser = Object.assign({}, user);
copiedUser.name = "花子";
console.log(user.name); // "太郎"(元のオブジェクトは影響を受けない)
console.log(copiedUser.name); // "花子"
2. structuredClone()
(ディープコピー)
const user = {
name: "太郎",
details: { age: 25, city: "東京" }
};
const clonedUser = structuredClone(user);
clonedUser.details.age = 30;
console.log(user.details.age); // 25(元のオブジェクトは変更されない)
console.log(clonedUser.details.age); // 30
8.5 まとめ
Object.defineProperties()
を使うと、複数のプロパティを一度に設定できるObject.getOwnPropertyDescriptors()
を使うと、オブジェクトのプロパティの詳細情報を取得できるObject.preventExtensions()
,Object.seal()
,Object.freeze()
を使ってオブジェクトの変更を制限できるObject.assign()
はシャローコピー、structuredClone()
はディープコピーを行う
9. よくある間違いとベストプラクティス
9.1 undefined
と null
の混同
間違い:undefined
と null
の違いを理解せずにプロパティを操作する
const user = {};
console.log(user.name); // undefined
console.log(user.age === null); // false(null ではない)
✅ ベストプラクティス
const user = { name: null };
if (user.name === null) {
console.log("値が設定されていません");
}
9.2 プロトタイプの影響を考慮しない
間違い:オブジェクトがプロトタイプを継承していることを意識せずにループを回す
const obj = Object.create({ inheritedProp: "プロトタイプのプロパティ" });
obj.ownProp = "自分のプロパティ";
for (let key in obj) {
console.log(`${key}: ${obj[key]}`);
}
✅ ベストプラクティス
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(`${key}: ${obj[key]}`);
}
}
9.3 Object.freeze()
の誤用
間違い:Object.freeze()
されたオブジェクトを変更しようとする
const config = { apiKey: "123456" };
Object.freeze(config);
config.apiKey = "newKey"; // 無視される
console.log(config.apiKey); // "123456"
✅ ベストプラクティス
const newConfig = { ...config, apiKey: "newKey" };
9.4 delete
の使用ミス
間違い:削除可能なプロパティをむやみに削除する
const user = { name: "太郎", age: 30 };
delete user.age;
console.log(user); // { name: "太郎" }
✅ ベストプラクティス
user.age = null; // 削除の代わりに null を代入
9.5 getter
の誤用
間違い:getter を使用しているのに ()
をつける
const person = {
firstName: "太郎",
lastName: "山田",
get fullName() {
return this.lastName + " " + this.firstName;
}
};
console.log(person.fullName()); // TypeError
✅ ベストプラクティス
console.log(person.fullName); // "山田 太郎"
9.6 プロパティの存在確認ミス
間違い:プロパティの存在確認に if (obj.property)
を使う
const user = { age: 0 };
if (user.age) {
console.log("年齢が設定されています");
} else {
console.log("年齢が未設定です");
}
✅ ベストプラクティス
if ("age" in user) {
console.log("年齢が設定されています");
}
9.7 まとめ
undefined
とnull
の違いを意識するfor...in
を使うときはhasOwnProperty()
でフィルタリングするObject.freeze()
されたオブジェクトを変更しようとしないdelete
の使用を避け、null
を代入することを検討する- getter を呼び出すときは
()
をつけない - プロパティの存在確認は
in
演算子を使う
10. FAQ(よくある質問)
10.1 プロパティとメソッドの違いは?
A1:
- プロパティ(property) は、オブジェクトのデータを保持するもの。
const user = { name: "太郎", age: 25 };
console.log(user.name); // "太郎"
- メソッド(method) は、オブジェクトの関数(処理を行うプロパティ)。
const user = {
name: "太郎",
greet() {
return "こんにちは";
}
};
console.log(user.greet()); // "こんにちは"
10.2 Object.defineProperty()
を使う理由は?
A2:
Object.defineProperty()
を使うことで、プロパティの詳細な制御(writable
、enumerable
、configurable
)が可能。- 例えば、値を変更できないプロパティを作成できる:
const user = {};
Object.defineProperty(user, "id", { value: 1001, writable: false });
console.log(user.id); // 1001
10.3 Object.freeze()
と Object.seal()
の違いは?
A3:
メソッド | 新しいプロパティの追加 | 既存プロパティの削除 | 既存プロパティの値の変更 |
---|---|---|---|
Object.freeze() | ❌(追加不可) | ❌(削除不可) | ❌(変更不可) |
Object.seal() | ❌(追加不可) | ❌(削除不可) | ✅(変更可) |
10.4 Object.keys()
と for...in
の違いは?
A4:
メソッド | プロトタイプのプロパティを含む | 列挙可能なプロパティのみ |
---|---|---|
for...in | ✅ 含む | ✅ |
Object.keys() | ❌ 含まない | ✅ |
例
const parent = { inherited: "継承プロパティ" };
const child = Object.create(parent);
child.own = "自身のプロパティ";
console.log(Object.keys(child)); // ["own"]
10.5 Object.assign()
と structuredClone()
の違いは?
A5:
Object.assign()
は シャローコピー(浅いコピー)structuredClone()
は ディープコピー(深いコピー)
シャローコピー(Object.assign()
)
const user = { name: "太郎", details: { age: 25 } };
const shallowCopy = Object.assign({}, user);
shallowCopy.details.age = 30;
console.log(user.details.age); // 30(元のオブジェクトも影響を受ける)
ディープコピー(structuredClone()
)
const user = { name: "太郎", details: { age: 25 } };
const deepCopy = structuredClone(user);
deepCopy.details.age = 30;
console.log(user.details.age); // 25(元のオブジェクトは影響を受けない)
10.6 まとめ
- プロパティとメソッドの違いを理解する
Object.defineProperty()
を使うと詳細な制御が可能Object.freeze()
は完全に変更不可、Object.seal()
は変更のみ可- プロパティの確認には
in
演算子かhasOwnProperty()
を使う Object.keys()
は自身のプロパティのみ取得、for...in
は継承プロパティも含むstructuredClone()
を使うとディープコピーが可能