JavaScriptのオブジェクトはプログラミングのデータ構造でいう、連想配列に似ています。つまり、名前と値の組のリストからなるデータ構造です。名前にあたる部分をプロパティと呼び、値がプロパティに関連付けられたデータに相当します。既にリテラルの項で見たように、オブジェクトリテラルは名前と値のペアからなっています
オブジェクトの表記
var o1 = { x:1,y:2}; var o2 = new Object(); o2.x = 1; o2.y = 2;
上のo1とo2はまったく同じデータをもつオブジェクトです。プロパティへのアクセスにはドット演算子を使っています。new Object()で新たなオブジェクトを生成し、o2.xのような形でプロパティと値を定義できます。これはグローバル変数がvarなしで定義できるのと似ています。ここで定義したオブジェクトを参照する方法も複数あります。
オブジェクトの参照
alert(o1.x); alert(o1['x'])
このようにドットを用いてプロパティ名を直接指定するか、[]でプロパティ名に当たる文字列を指定することでオブジェクトの値が参照できます。またオブジェクトからプロパティを削除するにはdelete演算子を使います
delete演算子でプロパティの削除
var o3 = { x:1,y:2}; delete o3.y; for(i in o3){alert(i);}
プロパティの存在確認にはin演算子を用いるか、!==演算子を使ってundefinedと比較します
in演算子
if('x' in o3)o3.x = 3; または if(o3.x !== undefined)o3.x = 3;
オブジェクトのプロパティと変数の違いは何でしょうか。実はこれらの間に大きな違いはありません。今までグローバル変数として定義していた変数はグローバルオブジェクトというオブジェクトのプロパティにあたるものになります。グローバルオブジェクトは、JavaScriptインタプリタが起動されると、コードを実行する前に生成されます。グローバルオブジェクトには組み込みの様々なオブジェクトやプロパティが定義されており、定数InfinityやparseInt関数、Mathオブジェクトなど様々なものが定義されます。プログラムのトップレベルではthisキーワードを用いることでグローバルオブジェクトが参照できます。次の短いコードで、グローバルオブジェクトにどんなプロパティが定義されているか確認できます。
グローバルオブジェクトのプロパティ
for(i in this){pn(i);}
クライアントサイドJavaScriptでは、windowオブジェクトがグローバルオブジェクトになります。上のthisをwindowに変えてコードを実行すると、ユーザ定義の関数なども表示されることが分かります。本サイトのインタプリタでは、こちらで動作を確認したほうが良いかもしれません
グローバル変数はグローバルオブジェクトのプロパティでしたが、ローカル変数はどうでしょうか。これはCallオブジェクトのプロパティです。関数の実行中、関数引数とローカル変数はCallオブジェクトのプロパティに格納されています。
変数の中身が何になっているか調べることを変数名の解決と言います。これを実現するために、スコープチェーンと呼ばれるものがあります。スコープチェーンはオブジェクトを並べたものです。変数xの名前を解決したい場合、最初のオブジェクトのプロパティに変数xがあるかを調べ、あればその値を返し、なければ次のオブジェクトから変数xがあるかを調べるという風にチェーンをたどりながら変数名は解決されます。関数の外側で定義されたJavaScriptコードの場合、スコープチェーンにつながるオブジェクトはグローバルオブジェクトだけです。しかし関数内で定義された変数の場合、スコープチェーンにつながるオブジェクトは、グローバルオブジェクトと関数のCallオブジェクトです。グローバルオブジェクトがグローバル変数、Callオブジェクトがローカル変数を管理しており、これらのスコープチェーンをたどることによってスコープは実現されています。