モジュール - JavaScriptの個人的なメモ (その5)

このメモについて

このメモは他の言語を習得している人用に向けて、それらとJavaScriptの違いを書いています。
誤りがあれば直しますので、ご指摘ください。

名前空間

JavaScript名前空間は、他の言語のと違って、名前の衝突を回避できません。

モジュール

モジュールは以下のように書いていきます。
まず、サンプルとして、関数a、bをあなたが作ったとしましょう。

  var a = function() {
        return 12;
      },
      b = function() {};

関数を入れておいた変数aとbは、実質的にグローバル変数です。
これを隠蔽して、モジュール化するには、前後に次のようなコードを挟めばいいです。

jModule = (function() { /* jModule: モジュールの名前 */

  var a = function() {
        return 12;
      },
      b = function() {};

  return function() {   /* モジュールのエクスポート */
    return {
      a: a,
      b: b
    };
  };
})();

さて、これでモジュールを作ることができました。関数aにアクセスするためには、jModule関数を経由する必要があります。
そのため、モジュールの外部では、変数aに直接アクセスできません。

jModule = (function() {
  var a = function() {
        return 12;
      };
  return function() {   /* モジュールのエクスポート */
    return {
      a: a
    };
  };
})();

a = 10;
jModule().a = function() { /* aメソッドを書き換えて0を返すようにする */
  return 0;
};
jModule().a();             /* しかし、12を返す */
モジュールのインポート

さっそく、先ほど作ったjModuleを、別のモジュールjModule2にインポートしてみましょう。

jModule2 = (function(ns) {
 var a = ns.a(); /* jModuleモジュール内の関数a を呼び出し */

  return function() {
    return {
      a: a
    };
  };
})(jModule());

いくつものモジュールを同時にインポートすることも可能です。

jHoge = (function(ns1, ns2, ns3) {
 /*..*/
})(jModule(), jModule2(), jModule3());

モジュールをあらかじめインポートしておけば、後から変数jModuleが書きかわっても問題は起きません。

結論

  • 変数について、名前の衝突を回避することは難しいです
  • モジュールは変数を隠蔽して、アクセス権のコントロールができます