JS

プロトタイプ

中級

読み方:プロトタイプ|英語:Prototype

オブジェクトが他のオブジェクトからプロパティやメソッドを継承する仕組みだよ。

やさしい説明

プロトタイプは、オブジェクトが他のオブジェクトからメソッドを「借りる」仕組みです。JavaScriptの継承はプロトタイプチェーンで実現されています。

配列で .map().filter() が使えるのは、Array.prototype にこれらのメソッドが定義されているからです。すべての配列がこのメソッドを共有しています。

class 構文は内部的にプロトタイプを使っています(シンタックスシュガー)。初心者のうちは class を使えば十分で、プロトタイプを直接触る必要はほとんどありません。

具体例・使い方

// 配列が .map() を使える理由
const arr = [1, 2, 3];
arr.map(x => x * 2); // Array.prototype.map を借りている

// プロトタイプチェーンの確認
console.log(arr.__proto__ === Array.prototype);  // true
console.log(Array.prototype.__proto__ === Object.prototype); // true
// arr → Array.prototype → Object.prototype → null
// (チェーンの末端はnull)

classとプロトタイプの関係

// class構文(現代の書き方)
class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name}: ...`; }
}

class Dog extends Animal {
  speak() { return `${this.name}: ワン!`; }
}

const dog = new Dog("ポチ");
dog.speak(); // "ポチ: ワン!"

// 内部的には Dog.prototype → Animal.prototype → Object.prototype
// というプロトタイプチェーンが作られている

class は ES2015 で導入されたシンタックスシュガーです。内部では同じプロトタイプの仕組みを使っていますが、class を使うことでより直感的に継承を書けます。

いつ使う?

  • 「なぜ配列に mapfilterforEach があるのか」を理解するとき
  • class の継承(extends)の動作原理を学ぶとき
  • 既存のエラーを読んで「prototype chain」が出てきたとき
  • ライブラリのソースコードを読むとき

間違いやすいポイント

❌ プロトタイプを直接変更する

Array.prototype に独自メソッドを追加するのは危険です。他のライブラリと名前が衝突したり、for...in でループしたときに意図しない要素が出てくることがあります。class を使って継承しましょう。

❌ __proto__ を直接使う

__proto__ は非推奨です。プロトタイプを調べたいときは Object.getPrototypeOf(obj)、設定するときは Object.create(proto) を使いましょう。

よくある疑問

Q: プロトタイプチェーンとは?

A: オブジェクトにプロパティがない場合、親(プロトタイプ)を辿って探す仕組みです。最終的にnullに到達すると探索終了です。

Q: classとprototypeの関係は?

A: classはprototypeベースの継承を書きやすくした構文です。class Dog extends Animal {} は内部でプロトタイプチェーンを設定しています。

Q: __proto__とprototypeの違いは?

A: __proto__はオブジェクトの親への参照、prototypeはコンストラクタ関数が持つ「子に渡すメソッド集」です。

関連用語

  • オブジェクト — プロトタイプチェーンの末端は Object.prototype
  • this — プロトタイプメソッド内の this はインスタンスを指す
  • 配列 — map・filter など配列メソッドは Array.prototype に定義されている

📖 関連レッスン

レッスンを見る →

関連ブログ記事

⚠️ 関連するエラー

❓ 関連するQ&A