【完全ガイド】JavaScriptのプロパティ徹底解説|基本から応用・ベストプラクティスまで

目次

1. はじめに

JavaScriptを使ってプログラミングをしていると、「プロパティ(property)」という言葉を頻繁に目にすることになります。プロパティは、オブジェクトのデータや状態を保持するための重要な概念です。本記事では、JavaScriptのプロパティについて基本から応用までを詳しく解説し、初心者から中級者まで理解できるように構成しています。

この記事を読むことで、以下のポイントが分かるようになります。

  • JavaScriptにおけるプロパティの基本概念
  • プロパティの作成・更新・削除方法
  • アクセス方法(ドット記法・ブラケット記法)
  • プロトタイプチェーンと継承の仕組み
  • 高度なプロパティ管理方法(Object.defineProperty() など)
  • よくある間違いとベストプラクティスまで

では、まずJavaScriptのプロパティとは何かについて見ていきましょう。

2. JavaScriptのプロパティとは?

2.1 プロパティの定義と役割

JavaScriptにおいてプロパティとは、オブジェクトに紐づくデータのこと です。JavaScriptのオブジェクトは、キー(名前)と値のペアで構成されています。この キーがプロパティ名 であり、対応する 値がプロパティの値 となります。

例えば、以下のようなオブジェクトを考えてみましょう。

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

この person オブジェクトには、nameagejob という 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: "太郎"
  • アクセサプロパティ: gettersetter を使って間接的に値を取得・設定するプロパティ

例えば、アクセサプロパティを使用すると、以下のように動的な値の取得や設定が可能になります。

const person = {
  firstName: "太郎",
  lastName: "山田",
  get fullName() {
    return this.lastName + " " + this.firstName;
  }
};

console.log(person.fullName); // "山田 太郎"

このように、アクセサプロパティを使うことで、プロパティの値を計算したり、特定のルールを適用することができます。

3. プロパティの作成と基本操作

3.1 プロパティの作成

JavaScriptでプロパティを作成する方法は大きく分けて2つあります。

  1. オブジェクトリテラルを使う方法
   const user = {
     name: "花子",
     age: 30
   };

{}(中括弧)を使ってオブジェクトを作成し、その中でプロパティを定義します。

  1. 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
enumerablefor...inObject.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, configurable3つの属性を理解 することで、安全なオブジェクト設計ができる
  • 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()); // "こんにちは!"

プロパティの検索の流れ

  1. childgreet プロパティがあるか確認 → ない
  2. child のプロトタイプ(parent)を調べる → ある
  3. 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 プロトタイプ継承の注意点

  1. プロトタイプの変更は避ける
  • Object.setPrototypeOf()__proto__ を頻繁に変更すると、パフォーマンスが低下する。
  1. ループ処理で継承プロパティを除外
  • 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...inObject.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 プロパティの列挙のベストプラクティス

  1. プロトタイプのプロパティを除外する場合は Object.keys() を使用
   const keys = Object.keys(obj);
  1. for...in を使う場合は hasOwnProperty() でフィルタリング
   for (let key in obj) {
     if (obj.hasOwnProperty(key)) {
       console.log(key, obj[key]);
     }
   }
  1. シンボルプロパティを含める場合は Object.getOwnPropertySymbols()
   const symbols = Object.getOwnPropertySymbols(obj);
  1. 値が必要なら 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 undefinednull の混同

間違い:undefinednull の違いを理解せずにプロパティを操作する

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 まとめ

  • undefinednull の違いを意識する
  • 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() を使うことで、プロパティの詳細な制御writableenumerableconfigurable)が可能。
  • 例えば、値を変更できないプロパティを作成できる:
  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() を使うとディープコピーが可能
広告