###前提・実現したいこと
名前空間について調べたのですが、色々な書き方が有ったり古かったりするのでどう書けばいいのかよくわかりません。es6で書く場合はこんな感じでいいですか。
###該当のソースコード
javascript
1const namespace = {}; 2namespace.a = 'a';// 変数 3namespace.function = function() {// 関数 4 console.log('test'); 5}; 6namespace.class = class {// クラス 7 constructor(params) { 8 this.params = params; 9 } 10};
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
ES5以前のJavaScriptにおいて、名前空間(namespace)という概念がそもそもありませんでした。各ファイルは単に結合されるだけだったため、グローバル変数の重複等による諸問題が発生する状態でした。その回避のために即時関数の使用や擬似的な名前空間の作成等のテクニックが編み出されました。
ES6(ES2015)から名前空間の概念が追加されました。ただ、ここで追加された名前空間は、一つのファイルないで名前空間を分けるという手法では無く、複数のファイルについて、それぞれが名前空間を持つ方式です。これがES6から追加されたモジュール(module)です。
ES6からモジュールとしてスクリプトファイルを読み込むという動作ができるようになりました。これまで、JavaScriptをHTML内で羅列した場合、それは単なるファイルの結合に過ぎませんでした。しかし、モジュールベースになった場合、それぞれが独立し、必要なものだけをやり取りできるようにしました。モジュールは次の点で通常のスクリプトファイルとは異なります。
- トップレベルのvar変数定義や関数定義がグローバルオブジェクトのプロパティ(グローバル変数)にはなりません。グローバルオブジェクトのプロパティとして明示的に作成しない限り、ファイル間で変数名や関数名の重複は発生しません
- 指定した変数、関数、クラスしか公開されません。トップレベルの変数であっても、公開しなければ、アクセス方法がありません。
- 自動的にstrictモードになります。
'use strict';
の汚染もありません。
このように、スクリプトファイル一つ一つが独自の名前空間を作成し、公開された名前を通してしか、やり取りできないようにしています。これがモジュールであり、ES6から追加された名前空間です。
モジュールの公開や読み込みにはexport
とimport
という新しい構文を使用します。export
でそのファイルにある変数等についてどれを公開するのか指定し、import
で指定した名前で他のファイルをモジュールとして読み込みます。
まずは、公開する側を見てみましょう。"myNamespace.js"というファイルを次のように作ってみます。
JavaScript
1var x = 'ex' 2export var a = 'a';// 変数 3export function f() {// 関数 4 console.log(x); 5}; 6export class K {// クラス 7 constructor(params) { 8 this.params = params; 9 } 10};
これを読み込んで、使用するには次のように書きます。
JavaScript
1import * as myNS from './myNamespace.js'; 2var x = 'in' 3console.log(myNS.a); // => 'a' 4myNS.f(); // => 'ex' 5let k = new myNS.K(0); 6console.log(k.params); // => 0 7console.log(x); // => 'in'
注目して欲しいのは、varで宣言されたx
です。もし、この二つのファイルが単なる結合であれば、x
は重複しているため、同じ物になるはずです。しかし、myNS.f()
での出力は'ex'ですし、その後のx
は'in'と違っています。これは、二つのファイルでx
はそれぞれ別の物として扱われるからです。つまり、名前空間がファイルによって異なると言うことです。
"myNamespace.js"のうち、直接アクセスできるのはexport
で明示的に公開しているa
、f
、K
に限定されます。import
文は色々書き方があるのですが、今回はmyNS
を最初に付けた形でそれらにアクセスするという風にしました。これで、公開された各変数、関数、クラスにアクセスできるようになり、また、それらが他のものと被ることもありません。
では、これはどうやって使えば良いのかというと、とっても簡単です。<script type="module">
というようにscriptタグのtype属性に"module"を指定するだけで、通常のJavaScriptではなく、このモジュールベースのJavaScriptとしてブラウザが読み込んでくれます。自動的にstrictモードになるなど、嬉しい機能が満載ですので、使わないという選択肢は無いでしょう。
ここで、残念なお知らせがあります。この素晴らしいモジュールの機能ですが、2017年7月11日現在正式に対応しているブラウザはSafariのみです。対応表を見ると、Edge、Firefox、Chromeは実験的に対応しているので、そのうち使えるようになりますが、IEが対応することはありません。なぜなら、IEの開発は既に終了しているからです。IEを捨てるという素敵な決断ができない場合はどうすれば良いのでしょうか?
ご安心ください。Babelで変換して、WebpackやBrowserifyで結合すれば同じ事ができます。Babelはrequire等を用いたCommonJSの形式にimport
とexport
を変換してくれます。あとは、CommonJSに対応したツールで一つにまとめれば良いのです。このとき、モジュール特有の名前空間も考慮して、一つにまとめてくれるので、IEでも(たぶん)うまく動いてくれるでしょう。
もうひとつ。Node.jsもまだ未対応です。ただ、こちらはそのうち対応する可能性が高いですが、それまでは同じくBabelで変換するしかありません。
投稿2017/07/11 11:25
総合スコア21735
0
typescriptをjavascriptに変換すると以下のようなコードとなります。
nekojiroさんのコードでも大筋問題はないと思います。
typescript
1namespace hoge { 2 const _a = 'a'; 3 4 const _func = () => { 5 console.log('func'); 6 } 7 8 export class _class { 9 constructor(params) { 10 this.params = params; 11 } 12 } 13}
↓
javascript
1var hoge; 2(function (hoge) { 3 var _a = 'a'; 4 var _func = function () { 5 console.log('func'); 6 }; 7 var _class = (function () { 8 function _class(params) { 9 this.params = params; 10 } 11 return _class; 12 }()); 13 hoge._class = _class; 14})(hoge || (hoge = {}));
投稿2017/07/10 13:43
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/14 10:59