(2001.10.11) 新規作成。
ECMAScript / JavaScriptは,プロトタイプベースな (prototype-based) オブジェクト指向言語。Java、Rubyなどメジャーなプログラミング言語は、プロトタイプベースではなく、クラスベース (class-based)。
プロトタイプベースのプログラミング言語には、例えば, 次がある.
クラスベースのオブジェクト指向言語では、まずオブジェクト (インスタンス) の雛型となるクラスを定義する。クラスにプロパティ (メンバ変数)、メソッドなどを定義する。オブジェクトはクラスから生成する。クラスが同じであれば, それぞれのオブジェクトは同じメソッドを持つ。
JavaScriptでは,クラスというものがなく、それぞれのオブジェクトにメソッド、プロパティを定義する。また、JavaScriptのオブジェクトはただのハッシュで、(プロパティ名: プロパティ値) の集まり。プロパティ値が関数であれば, それがメソッドになる。
JavaScriptでは、オブジェクトは 関数をコンストラクタと見立てる. この関数の名前 ( 次の例の [[Prototype]] 内部プロパティと、 コンストラクタの コンストラクタが何を返すかで, 生成されるオブジェクトが変わるのが微妙。 オブジェクトは、# 概要
# オブジェクトの生成
new演算子で生成する。
nameプロパティ) がクラス名になる.
new 関数オブジェクト ( 引数 )
Hoge() はただの関数。これを引数として new 演算子を実行すると, 次のような動作を行う;
new 演算子の対象F をコンストラクタとする.
TypeError を投げる.
"Object" とする
prototypeプロパティを持ち, それが Object である場合, それ.
Objectの prototype プロパティ
this は 1. で生成したオブジェクトを指す。引数は new演算子に与えたもの.
prototypeプロパティとは別物。
prototype プロパティにメソッドを設定することで、新しく生成されたオブジェクトのメソッドになる。
nullはプリミティブ値なので、コンストラクタがnullを返したときは新たに生成されたオブジェクトがnew演算子の値になる。下手にオブジェクトを返してしまうと、それになってしまう。
constructorプロパティを持ち、このプロパティはオブジェクトを生成した関数を指す。
JavaScript はクラスベースではないので、オブジェクトのクラスを差し替えることができる。
JSON文字列をオブジェクト化したもののクラスを差し替えてみよう。次の例は, Object.setPrototypeOf() を使い, Foo クラスオブジェクトに変更している。
JavaScriptのメソッドはただの関数で、オブジェクトのプロパティ値として参照されるもの。呼び出しのときのレシーバが Object.setPrototypeOf() は ES2015 (ES6) で導入された。[[Prototype]] 内部プロパティを変更する。
# メソッド定義
this に格納される.
メソッドはただの関数なので, レシーバなしでも呼び出せる。クラス間で使いまわしもできる。
レシーバなしに呼び出したとき, strictモードでは this は undefined になる。non-strictモードでは window になる.
this のスコープ関数がクラスに従属しないのが JavaScript の特徴だが、this が状況によって想定しないオブジェクトを指すのは、混乱のもとになることが多い。
this は、他の変数と異なり、dynamic scope を持つ。字面上の外側でなく, 呼出し元の値を引き継ぐ。
次の例の data.map() に与えている関数内の this は, lexical に外側の this にはならず, map() がレシーバなしで呼び出すために undefined になる。
this を強制的に固定するために, bind関数がある。呼び出しのつどレシーバを差し替えるのは call 関数.
次の例は, メソッド (実体はたたの関数) の this を固定するために, コンストラクタ内で bind() している。コンストラクタ内では, this は必ずクラスのオブジェクトになるので。
ES2015 (ES6) で導入された「アロー関数」(Arrow function) は、基本的には無名関数の短い書き方だが、this を lexically に束縛 (bind) する点がことなる。
アロー関数は、定義した時点の this を bind するので、上の例は呼び出し方に関わらず、this はクラスのオブジェクトを指すようになる。