当サイトは、アフィリエイト広告を利用しています
javascriptのプロトタイプチェーンについて仕組みや使い方よくわからなかったので
調べて動作を確認してみた。
クラスベースではオブジェクトの雛形として必ずクラスが存在し、
クラスをインスタンス化することでオブジェクトが生成されるのに対して
プロトタイプベースはオブジェクトは既存のオブジェクトを元(プロトタイプ)に作成される
組み込みオブジェクトのObjectオブジェクトのprototypeを元に作成される
const user = {name:"takesi",age:22};console.log(user.__proto__ === Object.prototype);console.log(Object.prototype);//true
protoにはObjectオブジェクトのプロトタイプが格納されている。
組み込みオブジェクトのFunctionオブジェクトのprototypeを元に作成される。
const func =(name)=> {this.name = name;};console.log(func.__proto__ === Function.prototype);// true
protoFunciontオブジェクトのプロトタイプが格納されている。
prototypeとprotoは完全に別物である。 ほぼ全てのオブジェクトはprototypeとprotoを持っている。
自身のプロトタイプが可能されている。
初期値では空オブジェクト{}になる。
またprotoからの参照先にもなる。
自身の製造元のオブジェクトのprototypeを参照している
要は
ので
protoを辿っていけば、最上位のObjectまでさかのぼることが可能になり、
この仕組みがプロトタイプチェーンと呼ばれる。
グローバルオブジェクトにあらかじめ定義されているオブジェクトで他のオブジェクトの基礎となる。
などがある
組み込みオブジェクトもprototypeとprotoを持っており、作成した
オブジェクトから辿ると下記のような感じになる。
const func = function (name) {this.name = name;};console.log(func.__proto__ === Function.prototype); //trueconsole.log(func.__proto__.__proto__ === Object.prototype);//trueconsole.log(func.__proto__.__proto__.__proto__);//null
最上位のObjectオブジェクトのprotoはnullになっている
プロトタイプチェーンを使ってtoStringを探す
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内を探しに行けることをプロトタイプチェーンという
プロトタイプチェーンの仕組みを使ってメソッド、プロパティを
を追加してみる
// オブジェクト定義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());//tadasiconsole.log(func3.call());//yamada// funcのprototypeをfunc2,3の__proto__で参照しているconsole.log(func2.hasOwnProperty("call")); //falseconsole.log(func2.__proto__.hasOwnProperty("call")); //trueconsole.log(func3.hasOwnProperty("call")); //falseconsole.log(func3.__proto__.hasOwnProperty("call")); //true
製造元のプロトタイプを定義することで、protoを使って
メソッドを呼ぶことができる。
newでオブジェクトを作成した場合は、その分新しいオブジェクトが作られてしまうが
こうすることで不要なメソッドコピーを減らすことができる
function( ){ } 構文で定義された関数のこと。
const constructorFunc = function(name){this.name}const sample = new constructorFunc("tanaka");
function( ){ } 構文なので問題なくnewできる
下記はコンストラクタ関数でないためnewできない。
色々調べてみて、感覚的には理解できたが言語化するのが難しかった。
javascriptがどのような仕組みでオブジェクトを作成しているかがわかったので勉強にはなったが
prototypeを実際使うような場面があまり思いつかない。
※現状、reactを触っているがほぼほぼ関数で書いてしまうため
下記を参考にさせて頂きました。
図なども多くとてもわかりやすいです!