当サイトは、アフィリエイト広告を利用しています

【javascript】プロトタイプチェーンの仕組みと使い方

作成日:2022月05月20日
更新日:2024年03月02日

javascriptのプロトタイプチェーンについて仕組みや使い方よくわからなかったので
調べて動作を確認してみた。

javascriptはプロトタイプベースの言語

クラスベースではオブジェクトの雛形として必ずクラスが存在し、
クラスをインスタンス化することでオブジェクトが生成されるのに対して プロトタイプベースはオブジェクトは既存のオブジェクトを元(プロトタイプ)に作成される

プロトタイプベースのオブジェクトを作成

オブジェクトの場合

組み込みオブジェクトのObjectオブジェクトのprototypeを元に作成される

index.js
const user = {name:"takesi",age:22};
console.log(user.__proto__ === Object.prototype);
console.log(Object.prototype);//true

protoにはObjectオブジェクトのプロトタイプが格納されている。

関数の場合

組み込みオブジェクトのFunctionオブジェクトのprototypeを元に作成される。

index.js
const func =(name)=> {
this.name = name;
};
console.log(func.__proto__ === Function.prototype);// true

protoFunciontオブジェクトのプロトタイプが格納されている。

参考

prototypeと protoについて

prototypeとprotoは完全に別物である。 ほぼ全てのオブジェクトはprototypeとprotoを持っている。

prototypeとは?

自身のプロトタイプが可能されている。
初期値では空オブジェクト{}になる。
またprotoからの参照先にもなる。

protoとは?

自身の製造元のオブジェクトのprototypeを参照している

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

要は

  • オブジェクトはprototypeとprotoを持っている。
  • protoには製造元オブジェクトのprototypeを参照している。

ので
protoを辿っていけば、最上位のObjectまでさかのぼることが可能になり、
この仕組みがプロトタイプチェーンと呼ばれる。

組み込みオブジェクトとは?

グローバルオブジェクトにあらかじめ定義されているオブジェクトで他のオブジェクトの基礎となる。

  • Functionオブジェクト
  • Objectオブジェクト

などがある
組み込みオブジェクトもprototypeとprotoを持っており、作成した
オブジェクトから辿ると下記のような感じになる。

index.js
const func = function (name) {
this.name = name;
};
console.log(func.__proto__ === Function.prototype); //true
console.log(func.__proto__.__proto__ === Object.prototype);//true
console.log(func.__proto__.__proto__.__proto__);//null

最上位のObjectオブジェクトのprotoはnullになっている

toStringメソッドを探すサンプル

プロトタイプチェーンを使ってtoStringを探す

index.js
const func = function(name){
this.name = name;
}
// funcにtoStringが存在するか?
console.log(func.hasOwnProperty('toString')); // false
// func.__proto__に存在するか?
console.log(func.__proto__.hasOwnProperty('toString')); //true
// func.__proto__はFunctionオブジェクトのprototypeを参照している
console.log(func.__proto__ === Function.prototype);//true
// Functionオブジェクトのプロトタイプに'toString'があるか?
console.log(Function.prototype.hasOwnProperty('toString'))//true

上記ようにprotoを辿ってprototype内を探しに行けることをプロトタイプチェーンという

プロトタイプの利用

プロトタイプチェーンの仕組みを使ってメソッド、プロパティを
を追加してみる

js
// オブジェクト定義
const func = function (name) {
this.name = name;
};
// funcを元にfunc2,3を生成
const func2 = new func("tadasi");
const func3 = new func("yamada");
// 存在チェック
console.log(func2.hasOwnProperty("call")); //false
// func(製造元)のprototypeに追加
func.prototype.call = function () {
return this.name;
};
// func2でも使える
console.log(func2.call());//tadasi
console.log(func3.call());//yamada
// funcのprototypeをfunc2,3の__proto__で参照している
console.log(func2.hasOwnProperty("call")); //false
console.log(func2.__proto__.hasOwnProperty("call")); //true
console.log(func3.hasOwnProperty("call")); //false
console.log(func3.__proto__.hasOwnProperty("call")); //true

製造元のプロトタイプを定義することで、protoを使って
メソッドを呼ぶことができる。
newでオブジェクトを作成した場合は、その分新しいオブジェクトが作られてしまうが
こうすることで不要なメソッドコピーを減らすことができる

コンストラクタ関数とは?

function( ){ } 構文で定義された関数のこと。

コンストラクタ関数

index.js
const constructorFunc = function(name){
this.name
}
const sample = new constructorFunc("tanaka");

function( ){ } 構文なので問題なくnewできる
下記はコンストラクタ関数でないためnewできない。

  • アロー関数
  • newで作成したオブジェクト

まとめ

色々調べてみて、感覚的には理解できたが言語化するのが難しかった。
javascriptがどのような仕組みでオブジェクトを作成しているかがわかったので勉強にはなったが
prototypeを実際使うような場面があまり思いつかない。
※現状、reactを触っているがほぼほぼ関数で書いてしまうため

参考

下記を参考にさせて頂きました。
図なども多くとてもわかりやすいです!

新着記事

タグ別一覧
top