関数をオブジェクトとして捉える

こんばんは。予定の日数をはるかに過ぎて未だに基礎的な勉強を続けております。
てわけでここしばらくで思い切り引っかかってたのが上の件。
以下、何に引っかかっていてどう理解に至ったのかという話。……たぶん。

1)事の経緯

今までのJavaScript理解はあくまで文字列操作の範囲のみでした。IRCで利用してるわけだから当然そうなります。
ので、新たにWebサイトでJavaScriptを利用する学習のために本を1冊購入。

Webサイト制作者のための JavaScript入門講座

Webサイト制作者のための JavaScript入門講座

なぜこの本を選んだかというと(というかネット上に講座があふれかえってるJavaScriptでなぜわざわざ本を購入したのかというと)、この本ではHTMLとJavaScriptのファイルを分けて作ることを徹底していたから。
初手からほとんどHTML内にJavaScriptを書くということをしません。
こういう方がメンテナンス性いいだろうと、どうせ覚えるならそういう方向で覚えたいと思いました。


が、そうすると当然ファイルが分かれるわけで。ファイル分かれた場合の、たとえばHTMLのフォームに入力された値はどうやってJavaScript側から参照すればいいのかが分からないわけで。
そこのところをわかりやすく教えてくれる物を探していた末にたどり着いたのが本書です。
……うむ、長かった。


ちなみに本書、各章ごとに最初にその章で実行したいことがズバリ書いてあるスクリプトが載っていて、その後に細かく解説が載ってます。実行したいこと、も具体的でなおかつ「サイトでやってみたいわ―」と思えることを例にしてくれてるので取り組みやすいです。そしてスクリプトが章の最初にずらっと書いてあるので後から振り返りやすくてわかりやすいです。……よくある編集だったらすいません。

2)引っかかった箇所

で、本を最初のページから割と真面目に読み進んでいって、引っかかったのがこれ。

//HTMLの読み込みを終了してから処理hogeを開始
window.onload = hoge;

function hoge(){
  //idが'hoge-id'の要素を指定して取得
  var hogeObj = document.getElementById('hoge-id');

  //'hoge-id'の要素にマウスイベントを設定。マウスオーバーでhogemouseon関数が実行される
  hogeObj.onmouseover = hogemouseon;
  //マウスカーソルが外れたらhogemouseoff関数が実行される
  hogeObj.onmouseout = hogemouseoff;
}

//'hoge-id'の要素にマウスカーソルが乗った時に実行される関数を定義
function hogemouseon(){
  this.className = 'active';
}

//'hoge-id'の要素からマウスカーソルが外れた時に実行される関数を定義
function hogemouseoff(){
  this.className = '';
}

hoge-idというIDがつけられたhtml内の要素にマウスカーソルが乗った時にだけ色を変える、というスクリプトです。
CSSには当然その指定が。

.active{
  background : red;
}

HTMLの特定の要素にマウスカーソルが乗った時だけその要素の背景が赤くなります、という記述。

3)ソースを読んだ時の誤解と理解

自分はこのソースを読んだ時、以下のように考えてしまいました。

  1. HTMLが読みこみ終了した後、hogeという関数が1度だけ実行される
  2. hogeという関数の中では、hogemouseon、hogemouseoffという2つの関数が呼び出され、即実行される
  3. あれ、てことはこのスクリプトはHTML読み込み時に全ての関数が実行されちゃうから、マウスをhogeオブジェクトに乗せても乗せなくても色変わったりしなくね?
  4. でもこのJavaScriptCSSを読み込んだHTMLファイルをブラウザで表示すると、ちゃんと背景の色が変わる。なぜ?

……2番の時点ですでに間違ってますね。


正しくは2番は、
hoge-idという要素に対して、マウスオーバー時とマウスカーソルオフ時イベントをそれぞれ設定している」
……ていう言い方でいいんだろうか。
ええと、とにかく関数自体を実行しているのではなく、関数という手続きをひとまとめ(オブジェクト)にして、マウスカーソルが乗っかったよとブラウザから通知が来た時に実行するよう予約している(メソッドとして対象のhoge-idオブジェクトに格納している)、のだと思います。
……うーん、なんだか不安な理解だ。

与太話)オブジェクトについて

自分の理解のためだけに書いてるので大変回りくどいです。ご注意。


そもそもオブジェクトってものについての理解があやふやだということがここでとても良くわかりました。
師匠的存在には「要するにポインタだ。フォームも関数もメモリ上に格納されたデータだ」と言われたんですが、この解説はそれはそれでなんとなく分かる感じがしたんですがまあちょっと脇に置いといて。


この一件のおかげで、自分がオブジェクトとかオブジェクト指向プログラミングというものに初めて触れたのがAccessだったので、オブジェクトってものについて大変即物的な理解をしてることがわかりました。
以下はAccessを例にしての話。

1)Accessでは、テーブル、とか、フォーム、ってモノを作ります。テーブルは実行した時の見た目が表計算ソフトみたいなモノで、データ一覧の格納場所、もしくは格納するカゴ、フォームは入出力の画面。これはモノとして、すなわちオブジェクトとして大変わかりやすいです。なにせ目の前にモノが見えるので。
2)さて、テーブルのデータはそのままナマで使うことは少ないです。というかそのままだと順番めちゃめちゃにデータ入ってたりして人間の目には優しくない一覧です。なのでたくさんのデータの中から特定のデータだけを抜き出したり、あるいは順番を入れ替えて人間がわかりやすいように表示するためにクエリーというものがあります。
たとえば順番も種類もごちゃまぜに入ってるDXのエフェクトのデータ一覧から、エンジェル・ハイロゥのエフェクトだけをアイウエオ順で並べたいとする。その場合、クエリーを新規作成して、そこに「エフェクト一覧からエンハイのエフェクトのデータだけ引っ張り出し、アイウエオ順に並べて表示せよ」という命令を書く。で、実行ボタンを押すと望み通りのテーブルが表示されます。ただしこの時、本当にエンハイのデータだけ抜き出してアイウエオ順に並べたテーブルが作られるわけではありません。仮に作っただけのもので、実行をやめれば消えてしまいます。ついでに言うと、クエリーの正体はSQLというデータベースをあれこれいじる言語です。中身はただの文字列です。でも、これはやはりテーブル状のモノが目に見えるのでオブジェクトとして認識しやすいです。
3)さて、1)〜2)のことは表計算ソフトでもそれなりに実行可能です。ていうかベタに情報を入力して、表計算ソフトの機能で整理したりしてもいけることです。ここからがAccessの本領発揮。
表計算ソフトで一覧に横にズラズラと入力していくのは入力ミスが起こりやすい危険な作業です。そこで入力用フォームを用意し、テーブルに登録する前に入力事項が間違ってないかチェックします。チェックするには関数などを使います。関数とは「ひとかたまりにした手続き」です。中身はVBAでがしがし書いてます。つまり文字列です。文字列によって表記された手続きの文書です。これを、「フォームの登録ボタンが押された時に実行するようにフォームに記録する」=「フォームの中の登録ボタンのプロパティ画面を表示し、マウスクリックイベントという名前の空欄にこの関数を登録する」と、実際に関数が動きます。これはオブジェクトでしょうか?
……これもオブジェクトなんですよねえ。関数というひとかたまりのオブジェクト。そしてこういう時、関数オブジェクトは「メソッド」と呼ばれるんだそうです。


そうだったのか。


1)→3)の順で、どんどん抽象的になっていくわけですが。
これを、3)であっても実体のあるモノとして認識するのがオブジェクト指向ということらしいです。
……ってよくこんなわかってない頭で今までAccessいじってたな、自分。まあ「動けばいい」だったからなあ。

追記

本の執筆者さん、お一人ははてなーさんだったんですね! リンク張ってから知ってびっくりした。

追記の追記

1人どころか3人ともはてダ利用者でいらした……。IDコールしたくないので出しませんが、書籍のリンクから容易にたどれます。