JavaScriptのオブジェクト
オブジェクトはJavaScriptで最も重要なデータ構造です。インフォメーションカードのように考えましょう。表面には「名前:花子」、裏面には「年齢:20」と書かれています。各情報にはキーと値があり、キーと値のペアを形成します。
📖 まとめ
オブジェクトリテラルの作成
波括弧{}を使ってオブジェクトを直接記述します。これが最も一般的な方法です:
<script>
const student = {
name: "花子",
age: 20,
major: "コンピュータサイエンス"
};
console.log(student);
</script>
キーと値のペアはコロンで区切られ、ペアはカンマで区切られます。最後のペアの後にカンマを付けることもでき、将来の追加に便利です。
プロパティへのアクセス
オブジェクトのプロパティにアクセスする2つの方法:
| 方法 | 構文 | いつ使うか |
|---|---|---|
| ドット記法 | obj.name |
プロパティ名が有効な識別子の場合 |
| ブラケット記法 | obj["name"] |
名前に特殊文字が含まれるか、変数に格納されている場合 |
ブラケット記法の最大の利点:変数をキーとして使用できることです。
<script>
const key = "name";
console.log(student[key]); // student["name"]と同じ
</script>
プロパティの変更と追加
オブジェクト作成後、いつでも既存のプロパティを変更したり、新しいプロパティを追加したりできます。constで宣言されたオブジェクトでも可能です(constは参照をロックし、内容はロックしない)。
<script>
student.age = 21; // 変更
student.grade = "3年生"; // 新しいプロパティを追加
console.log(student);
</script>
プロパティの削除
delete演算子でプロパティを完全に削除します:
<script>
delete student.grade;
console.log(student);
</script>
削除後、そのプロパティにアクセスするとundefinedを返します。
メソッド
オブジェクト内の関数はメソッドと呼ばれます。関数がプロパティの値になると、オブジェクトが「行動」できるようになります:
<script>
const dog = {
name: "レックス",
bark() {
return "ワン!僕は" + this.name;
}
};
console.log(dog.bark());
</script>
thisキーワード
thisは「現在のオブジェクト」を指します。メソッドを呼び出したのが誰かで、thisがそのオブジェクトになります。これはJavaScriptのもっとも厄介な概念の一つで、メソッドを抽出して別に呼び出すと、thisは元のオブジェクトを指さなくなります。
<script>
const bark = dog.bark;
console.log(bark()); // thisはdogを指さない — windowまたはundefinedになる可能性
</script>
コンストラクタ
同じ構造の複数のオブジェクトを一括作成する必要がある場合、コンストラクタ関数を使います:
<script>
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHi = function() {
return "こんにちは、僕は" + this.name + "です";
};
}
const p1 = new Person("太郎", 25);
const p2 = new Person("一郎", 30);
console.log(p1.sayHi());
console.log(p2.sayHi());
</script>
newは3つのことを行います:空のオブジェクトを作成 → thisをそこに設定 → オブジェクトを返します。
Object.keys / values / entries
この3つの静的メソッドは、オブジェクトのキー、値、キーと値のペアの配列を返します:
| メソッド | 戻り値 |
|---|---|
Object.keys(obj) |
["name", "age"] |
Object.values(obj) |
["花子", 20] |
Object.entries(obj) |
[["name","花子"], ["age",20]] |
オブジェクトの反復に非常に便利です:Object.keys(obj).forEach(key => ...)。
実例:学生オブジェクトの作成と情報表示
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>オブジェクト基礎</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.card { border: 2px solid #4a90d9; border-radius: 8px; padding: 16px; max-width: 360px; background: #f0f7ff; }
.card h3 { margin: 0 0 8px; color: #4a90d9; }
.card p { margin: 4px 0; }
</style>
</head>
<body>
<h2>学生情報カード</h2>
<div id="output"></div>
<script>
const student = {
name: "花子",
age: 20,
major: "コンピュータサイエンス",
gpa: 3.7,
introduce() {
return `私の名前は${this.name}です。${this.age}歳で、${this.major}を専攻しており、GPAは${this.gpa}です。`;
}
};
const output = document.getElementById("output");
output.innerHTML = `
<div class="card">
<h3>${student.name}</h3>
<p>年齢: ${student.age}</p>
<p>専攻: ${student.major}</p>
<p>GPA: ${student.gpa}</p>
<p><em>${student.introduce()}</em></p>
</div>
`;
</script>
</body>
</html>
実例:ドット記法とブラケット記法の比較
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>プロパティアクセス方法</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.result { background: #f5f5f5; padding: 12px; border-radius: 6px; margin: 8px 0; }
code { background: #e0e0e0; padding: 2px 6px; border-radius: 3px; }
</style>
</head>
<body>
<h2>プロパティアクセス比較</h2>
<div id="output"></div>
<script>
const user = {
name: "太郎",
age: 28,
"home-city": "東京"
};
const key = "name";
const results = [];
results.push(`user.name → ${user.name}`);
results.push(`user["name"] → ${user["name"]}`);
results.push(`user[key](key="name") → ${user[key]}`);
results.push(`user["home-city"] → ${user["home-city"]}`);
document.getElementById("output").innerHTML = results
.map(r => `<div class="result"><code>${r}</code></div>`)
.join("");
</script>
</body>
</html>
実例:プロパティの動的な追加、変更、削除
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>プロパティ操作</title>
<style>
body { font-family: sans-serif; padding: 20px; }
table { border-collapse: collapse; margin: 12px 0; }
td, th { border: 1px solid #ccc; padding: 8px 14px; text-align: left; }
th { background: #4a90d9; color: #fff; }
.action { color: #888; font-style: italic; margin: 8px 0; }
</style>
</head>
<body>
<h2>オブジェクトプロパティ操作</h2>
<div id="output"></div>
<script>
const product = { name: "ノートPC", price: 999 };
const log = [];
function showState(label) {
log.push({ label, snapshot: JSON.stringify(product) });
}
showState("初期状態");
product.price = 899;
showState("価格を899に変更");
product.brand = "レノボ";
showState("brandプロパティを追加");
delete product.brand;
showState("brandプロパティを削除");
const output = document.getElementById("output");
output.innerHTML = "<table><tr><th>操作</th><th>オブジェクト状態</th></tr>" +
log.map(r => `<tr><td>${r.label}</td><td>${r.snapshot}</td></tr>`).join("") +
"</table>";
</script>
</body>
</html>
実例:コンストラクタとObject.keys/values/entries
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コンストラクタとObjectメソッド</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.section { margin: 16px 0; padding: 12px; background: #f9f9f9; border-radius: 6px; }
.section h3 { margin-top: 0; color: #4a90d9; }
ul { padding-left: 20px; }
li { margin: 4px 0; }
</style>
</head>
<body>
<h2>コンストラクタと静的Objectメソッド</h2>
<div id="output"></div>
<script>
function Phone(brand, model, price) {
this.brand = brand;
this.model = model;
this.price = price;
this.showInfo = function() {
return `${this.brand} ${this.model} — $${this.price}`;
};
}
const p1 = new Phone("サムスン", "Galaxy S24", 899);
const p2 = new Phone("アップル", "iPhone 15", 999);
const keys = Object.keys(p1);
const values = Object.values(p1);
const entries = Object.entries(p1);
document.getElementById("output").innerHTML = `
<div class="section">
<h3>コンストラクタで作成したオブジェクト</h3>
<p>${p1.showInfo()}</p>
<p>${p2.showInfo()}</p>
</div>
<div class="section">
<h3>Object.keys(p1)</h3>
<ul>${keys.map(k => `<li>${k}</li>`).join("")}</ul>
</div>
<div class="section">
<h3>Object.values(p1)</h3>
<ul>${values.map(v => `<li>${v}</li>`).join("")}</ul>
</div>
<div class="section">
<h3>Object.entries(p1)</h3>
<ul>${entries.map(([k, v]) => `<li><code>${k}</code>: <code>${v}</code></li>`).join("")}</ul>
</div>
`;
</script>
</body>
</html>
❓ よくある質問
constで宣言されたオブジェクトのプロパティは変更できますか?constは変数の参照(常に同じオブジェクトを指すことを意味する)をロックしますが、オブジェクトの内容はロックしません。プロパティの追加、変更、削除は自由に行えますが、obj = {}のように再代入はできません。"home-city"など)、または動的アクセスのために名前が変数に格納されている場合は、ブラケット記法を使う必要があります。それ以外の場合は、ドット記法がクリーンで推奨されます。newを忘れた場合どうなりますか?thisがグローバルオブジェクトを指すようになり(厳密モードではundefined)、プロパティが間違った場所に配置されるかエラーが発生します。これは古典的な落とし穴で、ES6のclass構文では自動的に処理されます。📝 演習
title、author、yearプロパティと、"title by author, published in year"のような文字列を返すgetSummary()メソッドを持つbookオブジェクトを作成してください。- コンストラクタ
Car(brand, model, year)を書き、それを使って3台の車を作成し、Object.keysで1台の車のすべてのプロパティ名を一覧表示してください。 - 上記の車のいずれかに
drive()メソッドを動的に追加してください("brand model is driving"を返す)。呼び出して、メソッド内でthisが現在のオブジェクトを指すことを観察してください。



