2017年09月26日

JavaScriptとTypeScriptの名前空間について

開発部だより 第365回


TypeScript の名前空間について、「ああ、なるほど」と納得したことがあったのでそれを書いてみようと思います。

まずはじめに、JavaScriptには名前空間と言う機能は存在しません。
ですが、オブジェクトリテラル等を使用すれば名前空間を作成する事が出来ます。
var MYAPP = {};

こういうやつですね。O'REILLYの「JavaScriptパターン - 5.1名前空間のパターン」には、このグローバルオブジェクトを名前空間と呼んでいます。

ただ、この例のような名前空間と通常のオブジェクトには言語レベルの違いが無いので、JavaScriptの名前空間はあくまで概念的な意味が強いという事でしょうか。

次にTypeScriptのお話になりますが、TypeScriptでは名前空間(namespace)が使えます。
namespace MyNameSpace {
// ...
}

これは TypeScript 1.5 より前は内部モジュールと言う名前でした。モジュールと言う名前からもわかりますが、スコープとして他のモジュールとの名前衝突が避けられます。
そしてこれをトランスパイルすると、このようになります。
var MyNameSpace;
(function (MyNameSpace) {
// ...
})(MyNameSpace || (MyNameSpace = {}));

名前空間として付けた名前「MyNameSpace」がグローバル変数になって、その下の即時関数では「MyNameSpace」をオブジェクトとして扱っています。

結果 TypeScriptのnamespace「MyNameSpace」は関数で括られて、JavaScriptの名前空間「MYAPP」と同じ書き方になりました。

これを知った時、「今までJavaScriptで名前空間と言っていたオブジェクトは、本当に名前空間だったんだなあ」と納得しつつ感慨深い気持ちにさせられました。


また少し話が変わりますが、名前空間の利点の説明で複数人で開発する時に変数や関数名がかぶらないようにする(名前衝突の回避)と言うものを良く見ます。

確かにそのとおりなのですが、でもちょっと待っていただきたい。
複数人で開発して名前空間のおかげで名前の衝突が避けられるという事は、開発者それぞれが違う名前空間の下でプログラムをしているという事になりますね。
これでは「グローバルオブジェクトは一つが理想」に反してしまいます。それに名前空間で共有する変数は結局グローバルになってしまいますし。

この矛盾を解消するには、階層が深くなっても名前空間の下の名前空間(サブネームスペース)を作成するか、TypeScriptを使用してクラス化するか、もっと他に良い方法があるか、答えは一つではなさそうです。
posted by 開発部OliveDrab at 12:05
開発部だより | コメント(0)
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。