JavaScript | 実践:クラス継承 vs プロトタイプ継承の内部比較

javascrpit JavaScript
スポンサーリンク

ここでは、「クラス継承(class 構文)」と「プロトタイプ継承(prototype 直接操作)」の内部の違いを、初心者向けに「動作の中身」が見えるようにステップで比較していきます。

まずは全体イメージ

比較項目クラス継承(classプロトタイプ継承(prototype
構文の見た目JavaやPythonに似たスタイルちょっと低レベルで昔のJS方式
実態実は内部的には prototype を使っているprototype を直接操作して作る
学びやすさわかりやすい・直感的難しいけど仕組みが見える
推奨度✅ 現代JSの主流⚙️ 内部を理解したいときに学ぶ

ステップ1:クラス継承の例

// 親クラス
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} が鳴きます。`);
  }
}

// 子クラス
class Dog extends Animal {
  speak() {
    console.log(`${this.name} がワン!と鳴きます。`);
  }
}

const dog = new Dog("ポチ");
dog.speak(); // → ポチ がワン!と鳴きます。
JavaScript

📘 ポイント

  • extends は自動的に「親クラスの prototype を継承」します。
  • super() で親のコンストラクタを呼び出します。
  • 内部的には、Dog.prototype.__proto__ === Animal.prototype が成り立っています。

ステップ2:同じことを prototype で書くと…

// 親「コンストラクタ関数」
function Animal(name) {
  this.name = name;
}

// メソッドを prototype に定義
Animal.prototype.speak = function() {
  console.log(`${this.name} が鳴きます。`);
};

// 子「コンストラクタ関数」
function Dog(name) {
  // 親コンストラクタを呼ぶ
  Animal.call(this, name);
}

// 継承の仕組みを手動で設定
Dog.prototype = Object.create(Animal.prototype);
// コンストラクタ参照を修正
Dog.prototype.constructor = Dog;

// 子メソッドを追加
Dog.prototype.speak = function() {
  console.log(`${this.name} がワン!と鳴きます。`);
};

const dog = new Dog("ポチ");
dog.speak(); // → ポチ がワン!と鳴きます。
JavaScript

📘 ポイント

  • Object.create(Animal.prototype) で「親の prototype」をコピーしている。
  • Dog.prototype.constructor = Dog を設定しないと参照が狂う。
  • 実際の「class」構文は、これを裏で自動でやってくれている!

ステップ3:内部のつながりを可視化

console.log(Dog.prototype.__proto__ === Animal.prototype); // true
console.log(dog.__proto__ === Dog.prototype);              // true
console.log(dog instanceof Animal);                        // true
JavaScript

🔗 継承チェーン図(実際の内部構造)

dog
 └──> Dog.prototype
        └──> Animal.prototype
               └──> Object.prototype
                      └──> null

➡ つまり「クラス継承」も「プロトタイプ継承」も、最終的には 同じチェーン構造 になります。
class はただそれを「きれいな構文」で包んでいるだけです。

ステップ4:動作の比較まとめ

観点class継承prototype継承
メソッド定義class 内でメソッドを書くFunction.prototype に追加する
継承設定extends キーワードObject.create() 手動設定
super呼び出しsuper() で簡単Parent.call(this) 必要
可読性高い(直感的)低い(仕組み重視)
実行速度同等(中身は同じ)同等
主な用途現代のJS開発(推奨)低レベル理解・古いコード解析

練習課題(初心者向け)

1️⃣ 次の Cat クラスを作って、Animal を継承してみよう
2️⃣ Catspeak() メソッドを追加して "ニャー!" と出力
3️⃣ class 版と prototype 版、どちらも書いてみて比較!

まとめ

要点説明
JSのクラスは「糖衣構文」内部的には prototype ベースで動いている
プロトタイプチェーンメソッド探索の仕組み(親をたどる)
class構文人間が書きやすいように作られた表現方法
prototype理解クラス継承の裏側を理解するカギ
タイトルとURLをコピーしました