オブジェクトとプロトタイプ
JavaScriptのオブジェクトとは
- 関連のあるデータと機能の集合体
- もう少し厳密にいうと、プロパティの集合体であり、そのプロパティは名前(key)と値(value)を持つ
- オブジェクトがプロパティとして持っている関数をメソッドという
- keyには文字列またはSymbolが利用できる
- プロパティは名前と値以外にも、プロパティ属性という値を持つ
プロパティ属性
プロパティの値も属性の1つカウントすると、合計4つの属性があると言える
- 値
- 書き込み可(writable)
- 列挙可(enumerable)
- 再定義可(configurable)
これらの属性を調べるにはObject.getOwnPropertyDescriptor()を呼び出す。
Object.getOwnPropertyDescriptor({a: 1}, 'a')
=>
{
configurable: true,
enumerable: true,
value: 1,
writable: true
}
オブジェクトは以下の2つの意味で使われることがある
- Objectコンストラクタのインスタンス
- 非プリミティブ型を表すオブジェクト
前者も非プリミティブ型なので、前者は後者の部分集合と言えるだろう。
プロトタイプ
オブジェクト自身のプロパティ以外に、他のオブジェクトからプロパティを継承することができ、この継承対象となるオブジェクトをプロトタイプという。
プロトタイプとは
コンストラクタ内に保持されている特別なプロパティ。もしくはそのコンストラクタによって生成されたインスタンスが保持している特別なプロパティ。
「Object.prototypeはプロトタイプがない、まれなオブジェクトです」 by オライリー JavaScript
この記述からわかることは
- あるオブジェクトから見て、継承元になっているprototypeプロパティのことをプロトタイプと呼ぶ
- Object.prototypeにはプロトタイプがないが、Object.prototypeがプロトタイプになることはある(?)
プロトタイプはプロパティを指しているのか、もしくはそのプロパティとなっているオブジェクト(prototypeオブジェクト)を指しているのか曖昧なシーンがある、、
コンストラクタ
オブジェクトを生成するもの。
- クラス
- コンストラクタ関数(Objectの他にも、String、Arrayなどラッパーオブジェクトを作る関数)
クラス内のconstructorもコンストラクタと呼ぶのだが、クラスそれ自体もコンストラクタと呼ばれることがあるらしい。
コンストラクタの中にprototypeというkeyを持つプロパティが存在する。
コンストラクタによって生成されたインスタンスが保持している__proto__プロパティはプロトタイプか
- 「ほぼ全てのオブジェクトがプロトタイプを持つ」 by オライリー JavaScript
- 「JavaScript では、あるオブジェクトのインスタンスとそのプロトタイプ (コンストラクタの prototype プロパティから派生した __ proto __ プロパティ) の間にリンクが張られており、(省略)」 by MDN
という記述があるので__proto__もプロトタイプと呼べそう。
prototypeプロパティを持つオブジェクトは少数であり、このプロパティを持つオブジェクトが、他の全てのオブジェクトのプロトタイプを定義する。
Object
- JavaScriptのデータ型の一つを表す
- ほぼ全てのオブジェクトがObjectのインスタンスである。
- Objectコンストラクタ
Objectの中にはprototypeというkeyを持つプロパティが存在していて、そのvalueがprototypeオブジェクトと呼ばれている。
クラスベースとプロトタイプベース
クラスベース
言語
Ruby、Java、PHPなど
特徴
クラスをもとに新しいオブジェクトを作る。
extendsキーワードなどを使ってクラスを継承させたり、new演算子などを使ってインスタンスを作る
プロトタイプベース
言語
JavaScript
特徴
既存のオブジェクトから新しいオブジェクトを生成する(?)
JavaScriptにおけるクラスとは
特別な関数。
JavaScriptの関数はほぼ全てprototypeプロパティを持つ。
JavaScriptによる継承
「プロトタイプベースでの継承は、特別な操作ではなく、オブジェクト生成とまったく同じプロセスである。」 by サバイバルTypeScript
インスタンスの生成 = 親クラス(生成元のコンストラクタ)のプロトタイプを継承する
という発想になっている(?)