![]() |
前回まででクラスの重要な機能は一通り見てきたんだけど、
クラス関係でまだ説明してない機能があるから、今回からはその話ね。 …って言っても、今回から2章の終わりまでの内容は、知らなくてもそれなりにちゃんとしたスクリプトは書けるんだけどね。 |
![]() |
えっ、そうなの? じゃあ、別に説明しなくてもいいんじゃ… |
![]() |
まぁそうなんだけど、TJS の特徴的な機能だし、知っとくと便利な場合もあるからね。 |
![]() |
ふぅん…そうなんだ。 それで、今回はどんな内容なの? |
![]() |
§1.19 で関数の参照について説明したよね。 |
![]() |
えっと、確か変数を使って関数を呼び出す方法だったよね? |
![]() |
ん、そう。 メソッドとかメンバプロパティも変数を使って呼び出すことができるんだ。 で、この機能をクロージャって呼ぶの。 |
![]() |
クロージャ…? |
![]() |
とりあえず、クロージャを使った簡単なスクリプトを書いてみるね。 |
![]() |
うん。 |
<クロージャの使用例(その1)>
![]() |
MyDate クラスは説明しなくても解るよね? |
![]() |
Date クラスを使って今日が何月何日かを返す getDate メソッドがあるね。 |
![]() |
うん、そう。 で、クロージャの機能を使ってるのは、最後から3行目の『var closure = d.getDate;』以降の部分ね。 |
![]() |
メソッドの名前の後にカッコがついてないってことは、closure にはメソッドへの参照を代入してるってことだよね? |
![]() |
そ。書き方は関数の参照と同じでしょ。 |
![]() |
うん、そだね。 |
![]() |
じゃあ、その次の行の『System.inform(closure());』を実行するとどうなると思う? |
![]() |
関数の参照の時と同じように考えればいいんだよね。 えっと、『System.inform(d.getDate());』と同じになるんだから、今日が何月何日かが表示されるんじゃないかな? |
![]() |
うん、正解。 |
![]() |
じゃあ、結局クロージャって参照のことなの? |
![]() |
んー、まぁ参照って言えば参照なんだけど、クロージャの場合は、コンテキストの情報も持ってるんだ。 |
![]() |
コンテキスト? |
![]() |
コンテキストは、メソッドへの参照がどのオブジェクトのものかってことを表してるんだ。 例えば、closure の場合は d がコンテキストになるわけね。 |
![]() |
それって、closure は単に getDate メソッドへの参照っていうだけじゃなくて、 d っていうオブジェクトの getDate メソッドへの参照になってるってこと? |
![]() |
そう。だから、getDate メソッドへの参照は、オブジェクトごとに別々に作られるってこと。 |
![]() |
なるほどね。 |
![]() |
コンテキストについては次回詳しく見ていくから、その時に改めて説明するね。 |
![]() |
うん、りょーかい。 あ、そういえば、クロージャってどんな時に使うの? |
![]() |
ん〜、例えばこんな時に使えるかな。 |
![]() |
まず、MyDate2 クラスのプロパティを見てみて。 |
![]() |
year, month, day, week っていうプロパティがあるね。 それぞれ今の年、月、日、曜日を取得するプロパティみたいだね。 |
![]() |
ん、そう。 それじゃ、実行してみよっか。 |
![]() |
うん。 |
![]() |
これって、何を入力したらいいの? |
![]() |
『year』って入力してみて。 |
![]() |
はーい。 |
<year と入力した時のメッセージ>
![]() |
これって、year プロパティを参照したってことだよね? |
![]() |
ん、そういうこと。 あと、『month』『day』『week』も試してみて。 |
![]() |
おっけー。 |
<month と入力した時のメッセージ>
<day と入力した時のメッセージ>
<week と入力した時のメッセージ>
![]() |
month, day, week って入力すると、それぞれ month, day, week プロパティを参照するってことだよね? |
![]() |
そ。じゃ、スクリプトを見ていこっか。 |
![]() |
うん。 |
![]() |
まず、MyDate2 クラスのオブジェクトを作った後に、d のプロパティへの参照の辞書配列を作ってるでしょ。 |
![]() |
うん、closure っていう辞書配列の "year", "month", "day", "week" っていう要素に
d の year, month, day, week プロパティへの参照が代入されてるね。 この辞書配列の要素って、さっき入力した文字列なの? |
![]() |
そうそう。 それをチェックしてるのが『closure[element] !== void』って部分。 |
![]() |
element って inputString メソッドの戻り値だから、入力された文字列だよね。 |
![]() |
だから closure[element] が void じゃないってことは、 入力された文字列が "year", "month", "day", "week" のどれかってことになるんだ。 |
![]() |
え、そうなの? |
![]() |
うん。element が "year", "month", "day", "week" 以外だと、 closure[element] は void になるんだ。 |
![]() |
それって、"year", "month", "day", "week" 以外の要素にはまだ何も代入されてないから? |
![]() |
ん、そうだよ。 で、辞書配列の要素には year, month, day, week プロパティへの参照が入ってるわけだから… |
![]() |
入力された文字列によって、どのプロパティを参照するかが決まるってこと? |
![]() |
そういうこと。 クロージャを使うと、条件分岐を使わなくても、入力された文字列に応じて別々のプロパティを簡単に参照できるんだ。 |
![]() |
なるほどねー。 |
![]() |
今回は4つしかプロパティがなかったから、クロージャを使うメリットはそんなにないかもしれないけど、 プロパティやメソッドがもっと多かったり、複雑な処理をする場合はクロージャを使うと便利かもね。 |
![]() |
う〜ん、でもクロージャをうまく使ってスクリプトを書くのって結構難しそうかも… |
![]() |
まぁ大抵の場合はクロージャを使わなくても同じ動作をするスクリプトが書けると思うから、 クロージャは余裕があったら使ってみてね。 |
![]() |
うん、りょーかい。 |
![]() |
クロージャについてはこんなところかな。 それじゃ、また次回ね。 |