名前空間と自作ライブラリ
JavaScriptの名前空間とライブラリについて。
たぶん5年くらい「周回」遅れなネタなのではないかと思います。
JavaScriptは名前空間もしくは変数のスコープの問題が存在し、解決策が多くの方々により研究されているようです。
- JavaScript のブロックスコープと名前空間 « Mozilla Developer Street (modest)
- JavaScript 第5版 - 10章 モジュールと名前空間 - (DxD)∞
単純なルールとして、
- ドメイン名による命名(Javaのパッケージ命名規則のように)
- 無名関数を使ったローカルスコープの実現
を使うことで、グローバル変数の使用を最小限に抑えることができます。
比較的小規模の開発であれば、これでも良さそうな気がします。主に参照名が長くなってしまうのが欠点です。$をエイリアス用変数として使っています。(JSライブラリでは特殊なオブジェクトに使われることが多いようなので、併用する場合は別のものを使わないといけませんね。)
なお、今回はプロトタイプによる拡張については触れていません。(newしないとprototypeがコピーされないというのを学びました。)
- ライブラリっぽいもののサンプル
- IE8,Fx11,GC18で確認
<!DOCTYPE html> <html> <body> <br id="br1" /><hr id="hr1" /><br id="br2" /><hr id="hr2" /> <script language="javascript"> if (!net) var net = {}; net.argius = {}; net.argius.js = {}; net.argius.js.system = { p: function(o) { // debug print without console document.title = "" + o + "|" + document.title; } }; net.argius.js.collection = { a: function() { var $ = net.argius.js.collection; return new $.Array(arguments); }, asArray: function(o) { var $ = net.argius.js.collection; if (!o) return new $.Array(); if (o instanceof net.argius.js.collection.Array) return o; return new $.Array(o); } }; net.argius.js.collection.Array = function(o) { var arr = (o && (o.length || o.length == 0)) ? o : new Array(Number(o)); this.array = arr; this.length = arr.length; this.each = function(f) { for (var i = 0; i < this.array.length; i++) f(this.array[i]); }; this.concat = function(that) { if (!that.length) return this; var arr = new Array(this.length + that.length); for (var i = 0; i < this.length; i++) arr[i] = this.array[i]; var $ = net.argius.js.collection; var a = $.asArray(that); for (var i = 0; i < a.length; i++) arr[this.length + i] = a.array[i]; return new $.Array(arr); }; return this; }; (function(){ var p = net.argius.js.system.p; var a = net.argius.js.collection.a; var $ = net.argius.js.collection; p("START"); var arr1 = a("1", "2"); var arr2 = a("3", "4"); arr1.concat(arr2).each(function(o) { console.log(o); }); console.log("arr1 instance of argius.Array = " + (arr1 instanceof $.Array)); $.asArray(document.getElementsByTagName("*")).each( function(o){ if (o.id) console.log(o.id); }); p("END"); })(); </script> </body> </html>
- コンソールの出力結果
ログ: 1 ログ: 2 ログ: 3 ログ: 4 ログ: arr1 instance of argius.Array = true ログ: br1 ログ: hr1 ログ: br2 ログ: hr2