再入門JavaScript – 名前空間

Filed Under (Uncategorized) by on 29-10-2008

ネームスペース

ネームスペースとはwikipedia先生いわくこんな感じです。

名前の集合を分割することで衝突の可能性を低減しつつ参照を容易にする概念である。

Perlであれば

PERL:
  1. package XXX::YYY::ZZZ;
  2.  
  3. sub aaa{
  4.  
  5. }
  6. sub bbb{
  7.  
  8. }

とすれば、aaa,bbbはシンボリックテーブルXXX::YYY::ZZZ::において
XXX::YYY::ZZZ::aaa,XXX::YYY::ZZZ::bbbとして記録されグローバルに参照することができます。

なので仮に

PERL:
  1. package AAA;
  2.  
  3. sub aaa{
  4.  
  5. }
  6. sub bbb{
  7.  
  8. }

というモジュールをロードしても、名前は衝突することがありません。

JavaScriptの場合、シンボリックテーブルのようにstrictプラグマで保護されているようなグローバルハッシュは存在しないので
window以下のグローバルオブジェクトを使い名前空間を構築するほかありません。

JAVASCRIPT:
  1. (function(){
  2.     window.XXX = XXX || {};
  3.     window.XXX.YYY = XXX.YYY || {};
  4.     window.XXX.YYY.ZZZ = XXX.YYY.ZZZ || {};
  5.     window.XXX.YYY.ZZZ.aaa = function(){};
  6.     window.XXX.YYY.ZZZ.bbb = function(){};
  7. })();

しかし、このように記述していては冗長すぎるので、

JAVASCRIPT:
  1. var XXX = XXX || {};
  2. XXX.YYY = XXX.YYY || {};
  3. XXX.YYY.ZZZ = XXX.YYY.ZZZ || {};
  4.  
  5. (function(){
  6.     this.aaa = function(){};
  7.     this.bbb = function(){};
  8. }).apply(XXX.YYY.ZZZ);

のように書くことで、クロージャ内のスコープにおいて、thisがXXX.YYY.ZZZとなり、冗長な記述を避けることができます。

また、Prototype.jsのObject.extendを利用すれば

JAVASCRIPT:
  1. (function(){
  2.     Object.extend(this,{
  3.         aaa:export_aaa,
  4.         bbb:export_bbb
  5.     })
  6.     function export_aaa(){};
  7.     function export_bbb(){};
  8.    
  9. }).apply(XXX.YYY.ZZZ);

明示的にレキシカルスコープ中のどのメソッドを名前空間オブジェクトにバインドするかを記述することができます。

一方、

JAVASCRIPT:
  1. var XXX = XXX || {};
  2. XXX.YYY = XXX.YYY || {};
  3. XXX.YYY.ZZZ = XXX.YYY.ZZZ || {};

この部分の記述の冗長さは付きまとってしまうので、

これら名前空間に関する処理をひとつにまとめるメソッドをJS.Namespace

JAVASCRIPT:
  1. var ns =JS.Namespace.createNamespace('XXX.YYY.ZZZ');
  2. ns.aaa=function(){};
  3. ns.bbb=function(){};
  4.  
  5. or
  6.  
  7. JS.Namespace.createNamespace('XXX.YYY.ZZZ',function(){
  8.     Object.extend(this,{
  9.         aaa:export_aaa,
  10.         bbb:export_bbb
  11.     })
  12.     function export_aaa(){};
  13.     function export_bbb(){};
  14. });

のように記述することができます。

createNamespaceは新しいネームスペースを定義することを明示している関数です。
なので、すでにそのネームスペース/オブジェクトが存在している場合エラーを出力します。

これはファイル名とパッケージの結びつきの小さいjsにおいて、

* 名前空間を定義する場面
* その空間に関数/クラスを追加する場面
* その名前空間上の関数を利用する場面

というのをある程度明示しておくことで、開発上の混乱を避けるためです。

では次に名前空間に定義された関数を利用する場面での記述を考えて見ましょう。

Comments:

Post a comment