破棄されたブログ

このブログは破棄されました。

JavaScript のグローバル汚染防止策について

なんか微妙な記事を見かけて、どうせ何年も前の記事だろうってことでスルーしようかと思ったんだけど、よくみたら 2013 年の記事ですごく悲しい気持ちになったんでメモ。

問題の記事

下の記事で、上の記事のグローバル汚染防止方法についてツッコミをいれているわけだけど、単にアプローチが違うだけだよね。

名前空間

上の記事の daisuke って人は名前空間を作ってグローバル汚染を防いでる。

// 名前空間用オブジェクト
var NS = {};

// NS のプロパティに設定しているのでこれ以上グローバル汚染をしない。
NS.hoge = "hoge";

クロージャ

下の記事ではクロージャを使ってグローバル汚染を防いでる。

(function(){
  // クロージャ内で宣言された変数はグローバルを汚染しない
  var hoge = "hoge";
  // でも var を忘れると汚染する
  fuga = "fuga";
})();

単にそんだけでそ。まー daisuke って人の手法は書き方としては効率が悪いんで、クロージャと組み合わせるなり、ライブラリ使うなりしたほうがいいんじゃねーのとか思ったりもするけど。

他にも色々と思うところが…

グローバル変数JavaScript実行環境が提供してくれている window とかを参照するためのもので、自分で定義するものではありません。

こぶたのラッパ » JavaScriptでグローバル変数を使わない方法

window とかを参照するためのものっていうか、実行環境がブラウザの場合、window がグローバルオブジェクトそのものだったはず。それに、サンプルにある jQuery とかも現にグローバルを汚染してる。*1なんで、どっちかっていうと、 グローバルオブジェクトたる window オブジェクトのプロパティを上書きしてしまう可能性があるから、グローバル変数は絞ろうねってくらいの認識でいいと思う。あとグローバル依存はプログラムが密結合になるとかテスタしにくくなるとかそういう面もあるか。

JavaScriptコードはコピペしてなんぼのものが多いので、グローバル変数を使わずコピペされやすいコードを書きましょう!

こぶたのラッパ » JavaScriptでグローバル変数を使わない方法

おいやめろ。

ツッコミ歓迎

自分でクライアントサイドの JS 書くときは、グローバルで名前空間用関数作って、その後でクロージャ内に名前空間を注入するとかそういう感じで書くよん。

var NS = (function(){
  // 名前空間をクロージャ内に保持する
  var spaces = {};

  /**
   * 名前空間関数
   * @param  string 名前空間名
   * @return object 名前空間
   */
  return function(name) {
    // すでに存在すれば返す、存在しなければ初期化して返す
    return (namespaces[name]) ? namespaces[name] : namespaces[name] = {};
  };
})();

(function() {
  // 名前空間を作成
  var hoge = NS("hoge");
  hoge.fuga = "fuga";
})();

(function() {
  // 名前空間関数から変数を参照できる
  console.log(NS("hoge").fuga);
})();

動かしてみてないんで、動くかはわからん。JS のライブラリ事情をあまり知らないのと、ライブラリを投入するほどの大規模開発とは大変残念ながら縁がないのとで、実際のまともなプロジェクトでどういう実装されているかはわからん。
大規模開発だと、各 JS ファイルがビルド時にクロージャで包囲されるようにするとかなんかな? grunt とか使った開発してみたいね。


テスト駆動JavaScript

テスト駆動JavaScript

*1:一応内部で変数の退避もしてる