JavaScript プロトタイプ

 

 

JavaScript プロトタイプ: プロトタイプとプロトタイプチェーンを深く理解する

この記事では、JavaScriptのプロトタイプ(prototype)とプロトタイプチェーン(prototype chain)について、分かりやすく解説していきます。JavaScriptにおけるオブジェクト継承の仕組みを、根本から理解することができます。

プロトタイプ(Prototype)とは?

全てのJavaScriptオブジェクトは、プロトタイプオブジェクトを持っています。

  • プロトタイプオブジェクトもまた、オブジェクトの一種であり、独自の属性やメソッドを持つことができます。

  • オブジェクトの属性やメソッドにアクセスする際、もしオブジェクト自身に存在しない場合は、JavaScriptエンジンはプロトタイプチェーンを辿って上位層へ探しに行きます。

プロトタイプチェーン(Prototype Chain): オブジェクト継承の基盤

新しいオブジェクトが作成されると、そのオブジェクトはコンストラクタ関数のprototypeプロパティにリンクされます。

  • プロトタイプチェーンは、連結リスト構造をしており、オブジェクトとそのプロトタイプオブジェクトを結びつけ、最終的にはObject.prototypeに行き着きます。

  • Object.prototypeは、プロトタイプチェーンの頂点に位置し、そのプロトタイプはnullです。

__proto__プロパティとprototypeプロパティの違い

プロパティ 説明
__proto__ 全てのオブジェクトに存在し、そのプロトタイプオブジェクトを参照します。主にブラウザ内部で使用されます。
prototype 関数オブジェクトにのみ存在し、その関数が生成するオブジェクトのプロトタイプを指定します。

プロトタイプ継承の実践的な活用例

組み込みオブジェクトの拡張

Array.prototypeなどのプロトタイプオブジェクトを変更することで、組み込みオブジェクトに新しいメソッドやプロパティを追加できます。

Array.prototype.sum = function() {
  return this.reduce((a, b) => a + b, 0);
};

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // 出力: 15

オブジェクト継承の作成

プロトタイプチェーンを利用することで、クラスのような継承メカニズムを実現し、より簡潔で効率的なコードを書くことができます。

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(this.name + ' が鳴き声をあげます!');
};

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

const dog = new Dog('ポチ', 'ゴールデンレトリバー');
dog.speak(); // 出力: ポチ が鳴き声をあげます!

プロトタイプとパフォーマンス

プロトタイプチェーンを理解することで、より効率的なJavaScriptコードを書くことができます。

  • プロトタイプチェーン上での検索を深くしすぎないようにすることで、コードのパフォーマンスを向上させることができます。

まとめ

JavaScriptのプロトタイプは、JavaScriptのオブジェクトモデルを理解する上で非常に重要な概念です。プロトタイプとプロトタイプチェーンを理解することで、JavaScriptにおける継承メカニズムをより深く理解し、より美しく、効率的なコードを書くことができるようになります。

参考資料

  • MDN Web Docs: Inheritance and the prototype chain

  • JavaScript.info: Prototypes

QA

Q1: プロトタイプチェーンの頂点は何ですか?

A1: プロトタイプチェーンの頂点は Object.prototype であり、そのプロトタイプは null です。

Q2: あるプロパティがオブジェクト自身のものか、プロトタイプチェーン上のものか、どのように判断すればよいですか?

A2: hasOwnProperty() メソッドを使用することで、あるプロパティがオブジェクト自身のものかどうかを判断できます。このメソッドが true を返す場合、プロパティはオブジェクト自身のものであり、そうでない場合はプロトタイプチェーン上のものです。

Q3: プロトタイプオブジェクトを変更すると、どのような影響がありますか?

A3: プロトタイプオブジェクトを変更すると、そのプロトタイプオブジェクトを継承しているすべてのオブジェクトに影響します。ただし、組み込みオブジェクトのプロトタイプを変更すると、コードの互換性の問題が発生する可能性があるため注意が必要です。