図解つきで「オブジェクトの構造」と「thisの動き」をわかりやすく説明します。
テキストアート+アニメーションイメージ風で解説します。
JavaScript オブジェクトの構造
1. オブジェクトの中身のイメージ
オブジェクトは「名前つきの箱の集まり」だと考えると分かりやすいです。
const user = {
name: "Alice",
age: 30,
greet() { console.log("Hi!"); }
};
JavaScript内部イメージ:
user ─┬─ name → "Alice"
├─ age → 30
└─ greet → [Function]
name,age,greetは「キー(名前)」"Alice",30,functionは「値(value)」
2. プロトタイプチェーン(親オブジェクトの継承)
JavaScript のオブジェクトは「プロトタイプ(prototype)」を通じて
他のオブジェクトの性質を“引き継ぐ”ことができます。
const user = { name: "Alice" };
console.log(user.toString());
JavaScriptuser 自体には toString がありませんが、Object.prototype から引き継がれて使えます。
user
└── [[Prototype]] → Object.prototype
└── toString()
└── hasOwnProperty()
└── ...
🚩 JavaScript は「プロトタイプチェーン」を上にたどっていって、
目的のプロパティが見つかるまで探索します。
this の動き(超重要!)
1. this は「呼び出し元オブジェクト」を指す
const person = {
name: "Bob",
greet() {
console.log("Hi, I'm " + this.name);
}
};
person.greet(); // Hi, I'm Bob
JavaScript📊 イメージ:
呼び出し:person.greet()
┌───────┐
│ person │ this → person
│ ├ name: "Bob"
│ └ greet() │
└────────┘
👉 このとき、this は「person」を指す。
2. 呼び出し方を変えると this が変わる
呼び出し:say()
this → 何も指していない!(デフォルトでは undefined)
JavaScriptつまり:
| 呼び出し方 | this の中身 |
|---|---|
obj.method() | obj |
func() | undefined(またはグローバル) |
new Func() | 新しいオブジェクト |
func.call(obj) | obj に強制変更 |
3. 明示的に this を変える(call / bind)
const user = { name: "Alice" };
const pet = { name: "Doggo" };
function sayHi() {
console.log("Hi, I'm " + this.name);
}
sayHi.call(user); // Hi, I'm Alice
sayHi.call(pet); // Hi, I'm Doggo
JavaScript📈 図解:
sayHi.call(user)
↓
this → user
sayHi.call(pet)
↓
this → pet
まとめ図(全体イメージ)
┌───────┐
│ user │
│ ├ name: "Alice"
│ ├ greet() ────────┐
└───────┘ │
▲ │
│ this │
│ ▼
呼び出し元に応じて コンソール出力
this が変化する → "Hi, I'm Alice"
まとめ
| 覚えるポイント | 説明 |
|---|---|
| オブジェクトは「名前と値の集まり」 | { key: value } 形式で作る |
this は「呼び出し方」で決まる | obj.method() のときだけその obj を指す |
| プロトタイプで継承が起こる | obj → Object.prototype → null の階層構造 |
メソッドをコピーすると this が失われる | 参照の切り離しに注意 |
