togetter : JavaScriptの名前空間のスマートな使い方
ClockMakerさんのつぶやきから始まった、とても興味深いTLです。
JavaScriptの名前空間の汚染は神経質にならなくてはいけないポイントです。
言うまでも無いのですが、ゆるい言語なJavaScriptは型付ができないためにglobal領域に放り出された関数、変数をは容易に(思いもよらない)上書きが可能になります。
一人でコードを書いていれば注意さえすれば回避できる問題ですが、複数人がコード開発をしていたり、誰かが作成したコードを組み合わせて使わないといけないときにトラブルが起こりがちです。
jQueryとprototype.js の $()
コンフリクトはよく知られてますよね。
■名前空間を汚染しない
global属性に何も存在させなければ、そもそも問題は発生しません。
一番の理想ですけど、JavaScriptファイルを複数に分けたり、公開ライブラリを作成することができなくなります。
□名前空間の汚染を最小にする
これは、JavaScriptを書くときに自分に課してる規約です。
名前空間の汚染は最小にする。
つまり1個にする。
上書きされないように、パッケージのような名前にする。
com.inazumatv.behavior.DoSomthing
私は大文字の名前にすることが多いです。
COMINAZUMATV
全部大文字で入力するのめんどくさいですよね、ドメイン入れてるし、これで他人と被ることはないかなぁと…
■グローバル空間にexport する関数
uupa さんがメンションされたこの「export する関数」を使う方法は知りませんでした。
ただ、まだこの関数を使うメリットが理解できません。
「export する関数」自体がglobalに存在しなければ使えないように思え、現時点では「名前空間の汚染を最小にする」ルールから外れているようにしか考えられないからです。
ルールって言ってもオレオレなので破ったとしてもたいしたことはないんですけど。
namespace-js も知らなかったライブラリでした。
https://github.com/tanabe/Advent-calendar-2011
これも、まだメリットが理解できないなぁ。
■長い名前だと使うの大変
JSで、もし jp.clockmaker.data.MojaData クラスを作った場合、いつも new jp.clockmaker.data.MojaData() って書くのでしょうか?場合によってはローカル変数に名前空間を入れればすみますが。
WebGLで一躍有名になったJavaScriptライブラリのThree.jsですが、大文字の名前空間に違和感が…。クラス呼び出すときに、 new THREE.Object3D() って見栄えはもちろんのこと、タイピングも面倒だし、書き忘れが多発しそうです。
私はローカル変数で対処してます。
;(function ($iz) { var behavior = $iz.behavior ,do = behavior.DoSomthing ; })(COMINAZUMATV); |
あ〜、こうやってローカルで展開するときにnamespace-jsが便利なのかも。
今度試してみよう。
そうすると「export する関数」もローカル領域で使える?いや、使えない!?
なんかわかんなくなってきた。
画期的な解決策が見つかると嬉しいです。
【追記】
名前空間を汚染させずにコードを記述するには即時関数の中にコードを閉じ込めるのが一つの解決策だろうと思います。
と言うか、今のところこれしか思いつきません。
;(function () { //ここにコード }()); |
即時関数内のコードを他でも使いたい時は…
; var example = (function () { //ここにコード function Example () { } return Example; }()); |
こんな感じで取出して使っています。
ピンバック: 超個人的メモ, JavaScript関連の投稿リンクをまとめておく « イナヅマtvログ
ピンバック: JavaScript, Singleton Patternを作ってみた « イナヅマTVログ