IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

JavaScript でこんなパッケージ管理はどうか?

まず、以下のような package 関数を作る。

function package(name) {
  package.__hash__ = package.__hash__ || {};

  if (!package.__hash__.hasOwnProperty(name)) {
    package.__hash__[name] = {
      def: function(name, value) {
        return this[name] = value;
      }
    }
  }

  return package.__hash__[name]
}

で、こんな感じで使う

// ここは hoge の名前空間
with (package('hoge')) {
  def('var0', 1); // 変数は def 関数で定義
  def('var2', 2);

  alert(var0); // 1
  alert(var2); // 2
}

// ここは fuga の名前空間
with (package('fuga')) {
  def('var1', 3);
  def('var2', 4);

  alert(var1); // 3
  alert(var2); // 4
}

// ここは hoge の名前空間
with (package('hoge')) {
  alert(var0); // 1
  alert(var2); // 2
}

// ここは hoge と fuga の名前空間(あとに with した方を優先する)
with (package('hoge')) with(package('fuga')) {
  alert(var0); // 1
  alert(var1); // 3

  // fuga の名前空間を優先する
  alert(var2); // 4
}

この方法を使うと

グローバル変数*1を一切使わずに JS が書けます!

ちょっと解説

package 関数は、ただ def メソッドを持ったオブジェクトを返してるだけ
def メソッドは自分自身(オブジェクト)にプロパティを追加する。
with 文はスコープチェーンに、オブジェクトを追加する。
つまり、 def メソッドで追加されたプロパティが変数として見えるようになる。
って感じで動作してます><

まとめ

with を使うと遅いけど
速さを気にしないときに使おう!
便利!

*1:package 関数以外の