6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年1月17日 JavaScript (JS Primer) プロトタイプオブジェクト

前提(prototypeオブジェクトについて)

  • 正確には、ほとんどすべてのオブジェクトはObject.prototypeプロパティに定義されたprototypeオブジェクトを継承しています。
  • prototypeオブジェクトとは、すべてのオブジェクトの作成時に自動的に追加される特殊なオブジェクトです。
  • Objectのprototypeオブジェクトは、すべてのオブジェクトから利用できるメソッドなどを提供するベースオブジェクトとも言えます。

例えばtoStringメソッドはObjectのprototypeオブジェクトに定義があります。

// `Object.prototype`オブジェクトに`toString`メソッドの定義がある
console.log(typeof Object.prototype.toString); // => "function"

prototypeオブジェクトに組み込まれているメソッドはプロトタイプメソッドと呼ばれます。
prototypeの部分は省略しても同じ結果を得られます。

Objectのインスタンスは、このObject.prototypeオブジェクトに定義されたメソッドやプロパティを継承します。
つまり、オブジェクトリテラルやnew Objectでインスタンス化したオブジェクトは、Object.prototypeに定義されたものが利用できるということです。

本章に戻ります。

プロトタイプオブジェクト

プロトタイプメソッドインスタンスオブジェクトのメソッドをクラス内で同時に定義しても上書きされることもなければ、衝突することもありません。

なぜなら、それぞれ定義先が違うためです。

プロトタイプメソッド・・・プロトタイプオブジェクト

インスタンスオブジェクトのメソッド・・・インスタンスオブジェクト

プロトタイプオブジェクトとは、JavaScriptの関数オブジェクトのprototypeプロパティに自動的に作成される特殊なオブジェクトです。

function fn() {
}
// `prototype`プロパティにプロトタイプオブジェクトが存在する
console.log(typeof fn.prototype === "object"); // => true

class MyClass {
}
// `prototype`プロパティにプロトタイプオブジェクトが存在する
console.log(typeof MyClass.prototype === "object"); // => true

class構文のメソッド定義は、このプロトタイプオブジェクトのプロパティとして定義されます。

次のコードでは、クラスのメソッドがプロトタイプオブジェクトに定義されていることを確認できます。 また、クラスにはconstructorメソッド(コンストラクタ)が必ず定義されます。 このconstructorメソッドもプロトタイプオブジェクトに定義されており、このconstructorプロパティはクラス自身を参照します。

class MyClass {
    method() { }
}

console.log(typeof MyClass.prototype.method === "function"); // => true
// クラス#constructorはクラス自身を参照する
console.log(MyClass.prototype.constructor === MyClass); // => true

このように、プロトタイプメソッドはプロトタイプオブジェクトに定義され、インスタンスオブジェクトのメソッドとは異なるオブジェクトに定義されています。そのため、それぞれの方法でメソッドを定義しても、上書きされることはありません。

まとめ

  • プロトタイプオブジェクトとは、prototypeプロパティに自動的に作成される特殊なオブジェクトです。
  • プロトタイプメソッドとインスタンスオブジェクトに定義したメソッドの参照先は異なります。

参考

JavaScript (JS Primer) プロトタイプオブジェクト