FIG-047

プロトタイプチェーン — 自分に無ければ、上に聞く

ブラウザ 2026.06.24 公開 読了 約11分

JavaScript で dog.toString() と書けてしまうのは不思議です。dog という犬のオブジェクトに toString なんて自分では定義していないのに、なぜか動く。その秘密がプロトタイプチェーンです。オブジェクトは「自分に無いプロパティを聞かれたら、__proto__ という上の階に問い合わせる」という鎖でつながっています。

探し方はとてもシンプル。まず自分を見て、無ければ1つ上へ、それでも無ければさらに上へ。見つかった瞬間に止まり、終端の null まで行っても無ければ undefined です。下の図1で、アクセスしたいプロパティを選んでみてください。鎖を1段ずつ辿る様子が見えます。

PROTOTYPE CHAIN — 上から下へ __proto__ でつながっている
dog インスタンス
const dog = new Dog("ポチ")
name
Dog.prototype 犬の共通機能
bark
Animal.prototype 動物の共通機能
eat breathe
Object.prototype すべての大もと
toString hasOwnProperty
null 鎖の終端
これ以上は上がない → 見つからなければ undefined
READY
アクセスするプロパティを選ぼう
下のボタンを押すと、そのプロパティを dog から探し始めます。自分に無ければ __proto__ をたどって1段ずつ上へ。見つかったらそこで止まります。
図1 — 「自分に無ければ上へ」を繰り返す。dog.fly() は終端まで行っても見つからない

なぜこの仕組みが嬉しいのか

もし犬を100匹作るたびに barktoString を各オブジェクトへコピーしていたら、同じ関数が100個分メモリに散らばります。プロトタイプチェーンなら、共通の機能は Dog.prototype に1つ置くだけ。すべての犬がそれを「上の階」として共有します。class 構文で書くメソッドも、裏側ではこの prototype に収められています。

探索は下から上への一方通行です。だから自分の階に同じ名前のプロパティを持つと、上の階の同名プロパティは隠れて(シャドーイング)到達されません。図1の dog.toString() のように、最後まで辿ると必ず Object.prototype に行き着くのも、ほぼすべてのオブジェクトがそこを大もとに持つからです。なお「自分自身が持つか」だけを確かめたいときは hasOwnProperty を使い、鎖をたどらせません。

用語ミニ辞書
prototype
関数(コンストラクタ)が持つ、インスタンス共通の置き場所。メソッドはここに入る。
__proto__
各オブジェクトが指す「1つ上の階」への参照。探索はこれをたどって進む。
シャドーイング
自分の階に同名プロパティがあると、上の階の同名プロパティが隠れて見えなくなること。
Object.prototype
鎖のほぼ終端にある大もと。toString など共通機能が置かれている。

まとめ

プロトタイプチェーンは「自分に無ければ上へ問い合わせる」という、たった1つのルールでできた継承の仕組みです。共通機能を1か所に置いて全インスタンスで共有でき、メモリも節約できます。図1で dog.eat() を選ぶと2段、dog.toString() なら3段上って見つかり、dog.fly() は終端まで行って undefined になる —— 速さも継承も、この鎖を辿る動きから生まれているのです。