Open5

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

HironHiron

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コンストラクタのインスタンス
  • 非プリミティブ型を表すオブジェクト

前者も非プリミティブ型なので、前者は後者の部分集合と言えるだろう。

プロトタイプ

オブジェクト自身のプロパティ以外に、他のオブジェクトからプロパティを継承することができ、この継承対象となるオブジェクトをプロトタイプという。

HironHiron

プロトタイプとは

コンストラクタ内に保持されている特別なプロパティ。もしくはそのコンストラクタによって生成されたインスタンスが保持している特別なプロパティ。

「Object.prototypeはプロトタイプがない、まれなオブジェクトです」 by オライリー JavaScript
この記述からわかることは

  • あるオブジェクトから見て、継承元になっているprototypeプロパティのことをプロトタイプと呼ぶ
  • Object.prototypeにはプロトタイプがないが、Object.prototypeがプロトタイプになることはある(?)

プロトタイプはプロパティを指しているのか、もしくはそのプロパティとなっているオブジェクト(prototypeオブジェクト)を指しているのか曖昧なシーンがある、、

コンストラクタ

オブジェクトを生成するもの。

  1. クラス
  2. コンストラクタ関数(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オブジェクトと呼ばれている。

HironHiron

クラスベースとプロトタイプベース

クラスベース

言語

Ruby、Java、PHPなど

特徴

クラスをもとに新しいオブジェクトを作る。
extendsキーワードなどを使ってクラスを継承させたり、new演算子などを使ってインスタンスを作る

プロトタイプベース

言語

JavaScript

特徴

既存のオブジェクトから新しいオブジェクトを生成する(?)

HironHiron

JavaScriptにおけるクラスとは

特別な関数。
JavaScriptの関数はほぼ全てprototypeプロパティを持つ。

HironHiron

JavaScriptによる継承

「プロトタイプベースでの継承は、特別な操作ではなく、オブジェクト生成とまったく同じプロセスである。」 by サバイバルTypeScript

インスタンスの生成 = 親クラス(生成元のコンストラクタ)のプロトタイプを継承する
という発想になっている(?)