「必要なのはJavaScript言語仕様書とブラウザーコンソールだけ!」
シリーズ、その2。
仕様書によるとJavaScript実行環境では、大まかに2種類のオブジェクトが存在する。
##nativeオブジェクト
nativeという言葉には「原住民」という意味もあり、この場合も JavaScript言語の仕様 にその定義が含まれていることを指す。そのような基本的なオブジェクトのことを native オブジェクトと呼ぶ。
例:Object、Function、Boolean、Stringオブジェクトなどが代表的。
nativeオブジェクトの中でもbuilt-inオブジェクト(組み込み済みのオブジェクト)というものがある。非常に重要なオブジェクトなので、後で詳しく解説する。
##hostオブジェクト
逆に nativeでないオブジェクトをまとめてhostオブジェクトと分類している。
*host(ホスト)*という言葉は、例えば「ホームパーティーのホスト」のように使われる「場所を提供する」という意味合いがある。host環境の中でJavaScriptは実行するコンテクストを得る。ブラウザがホストに該当する。
Window、Location、Document等がhostオブジェクトの代表的なもの。それらはDOMの仕様としてJavaScript言語とは別に定義されているので、例えば「Window」とか「Document」に関する詳しい記述をJavaScript言語の仕様ページ内で探してもどこにもない。つまりそれらは native ではないということ。
hostオブジェクトの勉強は別の機会に。
#built-inオブジェクト(特に重要な native オブジェクト)
built-inオブジェクトは「組み込み済み」のオブジェクトであり、JavaScript言語を理解する上で最も重要な中心的概念といえる。
例えば、Object、Function、Boolean、String等のnativeオブジェクトが、build-inオブジェクトの代表的なもの。
##build-inオブジェクトは今すぐ見られる
仕様によると、built-inオブジェクトは実行環境が整い次第すぐに使えるとある。
コンソールに以下のようにbuilt-inオブジェクトを4つ、それぞれ別々に入力してEnterキーを押してみる。
どんな値が返ってくるだろうか?
Object
Function
Boolean
String
Objectという名前のfunction、Functionという名前のfunction(ややこしい!)、Booleanという名前のfunction、そしてStringという名前のfunction。4つともすべてfunctionだった!
え?function?
関数なの?
オブジェクトじゃないの?
##オブジェクトが functionってどういうこと?
ここで「???」となる人は私も含めて多分C言語などに慣れている人だと思う。built-inオブジェクトの名前を打ち込んだらもれなく「それはfunctionですよ」という答えが返ってきたから頭が混乱する。
15 Standard Built-in ECMAScript Objects(標準built-inオブジェクト)の段落3には、「ほとんどのbuilt-inオブジェクトはfunctionだ」とある。つまり、Object, Function、Boolean、String等は、それそのものが*call(呼び出し)*が出来る function だということ。
##Object を呼び出してみよう(なんか変な感じ・・・)
コンソールに、ただ単に「Object」と指定した場合と「Object()」というカッコつきの呼び出しの形で問い合わせてみる。
Object
Object()
Object
を指定した場合:「”Object”という名前が付いたfunctionです」
Object()
を指定した場合:「Objectというfunctionを呼び出しました。その結果がこれです」(なんか返ってきた!)
この4行目の Object {} には{}が付いていることに注目。これはJavaScriptの世界ではオブジェクトの属性などを示す際に使われる{}。つまり、オブジェクトが作られて、それが返されたってこと。
要点
カッコ尽きでbuilt-inオブジェクトの一つである Object を呼び出すと、新しいオブジェクトが作成され返される。Objectは呼び出し可能なfunctionである。
##返されたオブジェクトを変数に格納する
せっかく作ったオブジェクトが消えてなくなってしまうのは残念なので、変数を指定して、参照を保存する。
var x = Object()
x
x
変数xにオブジェクトの参照が格納されたので、何度でもそのオブジェクトを見ることが出来るようになった。ここで注意すべきは、オブジェクトそのものはメモリーのどこかに存在していて、xに格納されているのはあくまでもそのオブジェクトを指す参照。つまりxはオブジェクトの単なる別名(エイリアス)にすぎないことということ。
ではコンソールで作られたこのxという変数はJavaScript実行環境内のどこに保存されているのだろう。
#変数xはどこにあるのか?
上の例で作った、変数xはグローバル変数と言って、プログラムのどこからでもアクセスすることができる。グローバル変数は他にもたくさんあり、例えばhostオブジェクトの代表格、window変数(Windowオブジェクト)もグローバル変数としてアクセスできる。(window.Location = 'http://google.com' で、任意のページをロードする実験を覚えているだろうか)
変数を含むプログラム実行環境の詳細をみるには、プログラムの実行を一旦「paused 状態」にしなくてはいけない。そのために任意の行にbreak pointを仕掛ける。
<script>
ブロック内のどこか、例えば下のHTMLページなら、5行目にbreak pointを仕掛けて、もう一度F5キーでページをreloadする。
コードがbreak pointの位置まで到達して、スクリプトの実行がpaused状態になれば成功。
下はChromeでpausedになった状態。
上のスクリーンショットでは、中段右側のウィンドウが、グローバル変数をはじめとする、デバッグに役立つ様々な情報が表示される場所。
そのウィンドウに表示されている情報を「畳んで」見てみると下のようになっている。
ここにGlobalという項目がある。
展開して内容を見てみる。
全てのグローバル変数を見ることができる。いろいろと興味深いものが並んでいるが、さらに下までスクロールしてみると・・・
一番下に、xを発見。
xはObjectだと確認できる。
だがここに何か見慣れない __proto__
というのがある。これはいったい何だろうか? 実はこれがJavaScriptを理解するのにもっとも重要な仕組みの一つで、後で詳しく解説することにする。
#他のbuilt-inオブジェクトも呼び出してみよう
Object以外にも、built-inオブジェクトには Function、Boolean、String等がある(他にもArrayとかNumberとかある)
とりあえず、Function、Boolean、Stringオブジェクトを呼び出して、何が返ってくるかを調べてみる。
Function()
Boolean()
String()
Function: 名前がまだ無い空っぽのfunctionが返される。
Boolean: false が返される (おや? functionではない!)
String: 空の文字列が返される(これも functionではない!)
これは何が起きているかというと、オブジェクトにはそれぞれ「デフォルトの値・状態」に初期化された状態があり、オブジェクトによって異なる。Functionというオブジェクトは、呼び出されると function オブジェクトを作成するが、Booleanというオブジェクトは呼び出されるとデフォルト値(false)を返す。Stringオブジェクトは「空の文字列」というオブジェクトを返す。
これは何を意味するかというと、built-inオブジェクトはfunctionなのだが、それだけでなくconstructorと呼ばれる特別なfunctionだということ。
#ではconstructorとはいったい何?