気の向くままに辿るIT/ICT/IoT
JavaScript

JavaScript インスタンス化

ホーム前へ次へ
ECMAScriptベースのJavaScriptとは?

JavaScript インスタンス化

ECMA-262 Edition 5.1 / ECMAScriptベースのJavaScript文法

ECMAScript / ECMA-262 Edition 5.1ベースのJavaScript

プロトタイプベースのオブジェクト指向

オブジェクト指向 / オブジェクトと種類

インスタンス化

d = new Date() ;

 基になるオブジェクトの一定のプロパティをコピーし、当該オブジェクトの実体、より具体的な実例であるインスタンスを生成することを継承、または、JavaScriptでは、特にインスタンス化 / instantiation と呼び、GlobalオブジェクトMathオブジェクトJSONオブジェクトを除き、 new 演算子を伴うオブジェクト式を右辺として左辺の変数に代入することでインスタンスが生成されます。

 尚、それらの内、ArrayオブジェクトFunctionオブジェクトErrorオブジェクトと各種Errorオブジェクトについては、new 演算子を伴わない関数としての呼び出しにおいても同様にインスタンス化されます。

var func1 = function () { }

var func2 = new Function ( ) ;

 代入演算子を使用し、任意の変数に代入するとオブジェクトであるインスタンスが格納され、こうしてできたものは、単にオブジェクトまたは、インスタンス、インスタンスオブジェクトなどと呼ぶ場合があります。

 その際、オブジェクトの内部メソッドであるコンストラクタによる初期化処理が自動的に行われます。

Array.prototype

 インスタンスには、既定で当該オブジェクトのprototypeプロパティが持つプロパティが継承されることになっています。

Array.prototype.constructor

  prototype プロパティは、更にプロパティを持つのでオブジェクトでもあり、そのプロパティの1つに constructor プロパティがあり、constructorプロパティの初期値は、そのオブジェクト自身のコンストラクタ(としてのメソッド)であり、この値となるメソッドを設定することで初期化内容を一部、または、全部書き換えること(、いわゆるオーバーライド)も可能です。

d1 = new Date ( ) ; 

document.write(d1.getDate());

 よって、この例の インスタンスオブジェクト d1 は、Dateオブジェクトをインスタンス化する際、 Date.prototype オブジェクトが持つプロパティを継承することになります。

 その際にインスタンスオブジェクトには、prototypeオブジェクトではなく、その中身のプロパティが継承されるので "prototype"を介すことなく、直接、ドット記法を使ってDate.prototype オブジェクトが持っているのと同様の各プロパティにアクセスすることができます。

 元のオブジェクトのprototypeオブジェクトのプロパティの更新(追加、変更、削除)は、インスタンスにも動的に反映されますが、逆の影響はありません。

// i_nameはインスタンス変数

var obj = { "i_name" : "val" }

 オブジェクトで変数が定義されている場合、当該オブジェクトから共に継承した変数やインスタンス上で定義した変数はインスタンス変数と呼ばれる場合もあります。

インスタンス化しないオブジェクト

 尚、JavaScriptにおいては、参照時に"Global"は使用されないことになっているのでGlobalオブジェクトと、これ以外にMathオブジェクト、JSONオブジェクトについては、インスタンス生成機能や当該オブジェクト自体の関数としての呼び出し機能はありません。

 document.write('Object.getPrototypeOf(Object) is ' + Object.getPrototypeOf(Object) + "<br>" ) ; 

 // >> Object.getPrototypeOf(Object) is function () { }

 document.write('Object.getPrototypeOf(Math) is ' + Object.getPrototypeOf(Math) + "<br>" ) ; 

 // >> Object.getPrototypeOf(Math) is [object Object]

 

 ...etc.

 ブラウザによっては、以下でも確認可

 

 document.write('Object.constructor is ' + Object.constructor + "<br>" ) ; 

 // >> Object.constructor is function Function() { [native code] }

 document.write('Math.constructor is ' + Math.constructor + "<br>" ) ; 

 // >> Math.constructor is function Object() { [native code] }

 ...etc.

 但し、内部的、処理系・実装的には、Globalオブジェクトを除く基になるオブジェクトの内、インスタンス生成や関数としての呼び出しを行わないMathオブジェクトとJSONオブジェクトは、Object型を生成する為のメソッド、それ以外のオブジェクトはFunction型を生成する為の初期化メソッドを呼び出すものとされています。

function及びobjectとプロトタイプチェーン

 その場合、FunctionオブジェクトやObjectオブジェクト以外であっても、これに該当するオブジェクトは、Function.prototype や Object.prototype オブジェクトからも暗に一部プロパティを継承する場合があり、このような連鎖的なつながりは、プロトタイプチェーンと呼ばれます。

 インスタンスオブジェクト自身が持つプロパティなのか、プロトタイプチェーンのスコープ内のプロパティなのかは、引数としてプロパティをとるhasOwnProperty()メソッドで確認することが可能です(が、ちなみに何れにしてもブラウザ独自拡張の場合は、独自拡張か否かの判別まではできません)。

this キーワード

 this キーワードは、インスタンス(が任意のオブジェクトから継承した)オブジェクトとして代わりに参照可能な指示子です。

 よってJavaScriptでは、オブジェクトのプロパティである関数をメソッドと呼びますが、関数が、オブジェクトのメソッドとして呼ばれる場合、そのオブジェクトは、 this 値としてメソッドに渡されます。

 別の見方をするとオブジェクト定義内にあるthisキーワードは、そのオブジェクトを示します。

 特にインスタンスのメンバとそれ以外のローカル変数などを明確に識別する際に便利ですが、逆に this が、その時点でどのオブジェクトを指すのかが、曖昧である場合、思わぬバグを仕込む原因ともなり得ます。

ECMAScriptベースのJavaScriptリファレンス

ECMAScript / ECMA-262 Edition 5.1 日本語訳

ECMAScript / ECMA-262 第 5.1 版 訳

ホーム前へ次へ