もふもふ技術部

JavaScriptでprivateな変数とか関数を表現する


JavaScript The Good Partsを読む

JavaScriptを書く機会というのは、WEBアプリケーションエンジニアとしては画面の動的な制御だとかAjaxだとか、そういった用途で使うことが多いだろう。ともするとさほど高いレベルは必要なく割と「誰でも書ける言語」的な過小評価をされていることもしばしば。

でも実はJavaScriptって奥が深い言語で、いろんな表現方法をもっていて、コードの自由度が高くて、ちょっとトリッキーな感じになっちゃったりするところが趣味プログラマに好かれてたりもする。

そういうわけでこの本読んだ。
20代くらいでコーディングメインの若手WEBエンジニアが読むと「へーそんなんあったのか!」みたいな具合でそこそこ楽しめるんではなかろうか。

JavaScript The Good Parts / ダグラス・クロフォード著

そもそもの話

表題であげた通り、JavaScriptでprivateな変数とか関数を表現する方法を考えていきたいが、そもそもなんでprivateな変数とか関数が必要なわけ?って疑問がでてきた方はオブジェクト指向のアクセス権について勉強してくれよな。

詳しいことは割愛するが、publicとprivateを区別することでコードの意図が明確になり読みやすくなるというようなメリットがある。特にチームで仕事する場合はね。

クロージャという手段

これを表現するには「クロージャ」と呼ばれるテクニックを使う。クロージャとは…説明したいところだが、文章で説明するにはやや難があるものだから実例から理解するといいだろう。

失敗例1

これはそもそもJavaScriptの言語仕様をまるで理解してないと言える。

末尾に()がついているので右辺の関数の実行結果を変数myobjに代入するという命令になる。当然returnしていないので戻り値はundefined。myobjのメンバにアクセスしようとしても不可能だ。

そして実はこのコードの悪いところはもうひとつある。this.mogeのようにthisのメンバに代入しようとしている箇所だ。この場合、thisが示すのはグローバル領域になるため、window.mogeに代入されてしまい、悪しきグローバル汚染を引き起こす。

失敗例2

これは実際にぼくがやってしまった勘違いコードだ。これで期待している挙動を実現できるのだが可読性は著しく低い。このコードは失敗例1を無理矢理にカバーしているだけである。下記のローカルスコープを利用することでthisが示す値を操作しているだけなのだ。


つまりthisが示す値はローカルスコープとなる。myobjにオブジェクトのインスタンスを代入しようとしているつもりが、実際にはローカルスコープが返されているという状態になり、人が認識しやすい「オブジェクト」という表現から外れてしまう。

正しい例

右辺の関数の実行結果をmyobjに代入する。関数内で定義されたhoge, moge, pogeはfunctionのスコープに縛られることになるので外側からは参照できなくなる。そこで、外側からアクセス可能にするために、return部でmoge, pogeにアクセスしている関数(変数)を持ったオブジェクトを返している。hogeにアクセスする関数は用意していないので、これでhogeは完全にprivateな変数となる。

シンタックスシュガー

昨今ではCoffeeScriptやTypeScriptといったようなシンタックスシュガーが台頭してきている。ぼくもCoffeeScriptを使ったことがあるが、非常に使いやすい。記法もやさしいし、コンパイル後のコードを見るとJavaScriptの悪い部分をうまくカバーしてくれている(グローバル汚染の回避や==比較演算子の問題など)。

今後はこういったシンタックスシュガーが主流になり、生のJavaScriptを書く機会は減るだろうなーと思うと、嬉しくもありちょっとさみしくもある、そんな心境になったりしてね。

The following two tabs change content below.
原田 敦

原田 敦

日本CAWのエンジニア。もふもふ部の部長。得意分野はRuby on Railsを使った小規模WEBアプリケーションを高速で開発すること。週末の楽しみは一人お菓子パーティー。三度の飯より小動物をもふもふするのが好きです。