コンテンツにスキップ

JavaScript/プロトタイプチェーン

出典: フリー教科書『ウィキブックス(Wikibooks)』

概要

[編集]

プロトタイプチェーンは、JavaScriptの継承メカニズムの中核を成す重要な概念です。プロトタイプベースのオブジェクト指向プログラミングにおける継承と動的な属性解決を可能にする、言語の根本的な仕組みです。

プロトタイプの基本

[編集]

JavaScriptでは、各オブジェクトは内部的に別のオブジェクト(プロトタイプ)への参照を持っています。このプロトタイプから、オブジェクトは プロパティやメソッドを継承します。プロトタイプチェーンは、これらの継承関係を連鎖的に辿ることができる仕組みです。

プロトタイプの仕組み

[編集]

オブジェクトがあるプロパティやメソッドにアクセスする際、JavaScriptエンジンは以下の手順で解決を試みます:

  1. まず、そのオブジェクト自体に直接そのプロパティがあるかを確認
  2. なければ、オブジェクトのプロトタイプ(__proto__)を確認
  3. さらになければ、そのプロトタイプのプロトタイプへと遡る
  4. 最終的にObject.prototypeに到達するまで繰り返す

継承の仕組み

[編集]

コンストラクタ関数による継承

[編集]

伝統的なJavaScriptの継承モデルでは、コンストラクタ関数とプロトタイプを使用して継承を実現します:

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

Animal.prototype.speak = function() {
    console.log(this.name + " makes a sound");
};

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

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

Dog.prototype.bark = function() {
    console.log("Woof!");
};

ES6のclass構文

[編集]

モダンJavaScriptでは、class構文により継承がより直感的に記述できます:

class Animal {
    constructor(name) {
        this.name = name;
    }
    
    speak() {
        console.log(this.name + " makes a sound");
    }
}

class Dog extends Animal {
    bark() {
        console.log("Woof!");
    }
}

プロトタイプチェーンの特徴

[編集]

動的な継承

[編集]

プロトタイプチェーンは動的であり、実行時にプロトタイプを変更することができます。これにより、言語に柔軟性を与えています。

パフォーマンスへの影響

[編集]

プロトタイプチェーンが深くなると、プロパティ検索のパフォーマンスに影響を与える可能性があります。深い継承階層は避けるべきです。

プロトタイプ関連のメソッド

[編集]

Object.create()

[編集]

指定されたプロトタイプオブジェクトを持つ新しいオブジェクトを作成します。

Object.getPrototypeOf()

[編集]

オブジェクトのプロトタイプを取得します。

Object.setPrototypeOf()

[編集]

オブジェクトのプロトタイプを設定します(非推奨)。

注意点と落とし穴

[編集]
  • プロトタイプチェーンの過度に深い継承は避けるべき
  • パフォーマンスとコードの可読性に注意
  • 継承よりコンポジションを優先することが推奨される場合がある

現代的なアプローチ

[編集]

最近のJavaScriptでは、以下のような方法でオブジェクト指向プログラミングを行います:

  • ES6のclass構文
  • コンポジションパターン
  • モジュールパターン

結論

[編集]

プロトタイプチェーンは、JavaScriptの柔軟で動的な継承メカニズムの根幹を成す概念です。言語の特性を深く理解する上で、その仕組みを把握することは非常に重要です。