あまり新しくないもの

新しさはそんなに求めず、自分のすきなことをやりたい人生だった

javascriptでnamespaceを管理するやつ

jsで、一つのファイルにすべてのコードを詰め込むと、長くなってくると非常に読みにくいしどこに何があるのかよくわからないし、結局何をしているのか追いにくくなって保守性が最悪になります。

そのため、大抵の場合は役割とか関数とかクラス(っぽいもの)ごとにファイルを分けていくかと思います。そのとき、namespaceをしっかり管理しておかないと何かと不都合です。

そんなわけで、JavaScriptnamespaceを管理するのによく使ってるコード。

(function(global) {
    'use strict';
    var root = 'rootnamespace';

    global[root] = global[root] || {};

    function setNS(definition, namespace) {
        var ns = namespace || global[root],
            def = definition.split('.');
        var i=0,
            len = def.length;
        for(;i<len;i++) {
            ns = _setProp(ns, def[i]);
        }
    }

    /**
     * [オブジェクトにプロパティを配置]
     * @param {[object]} obj
     * @param {[string]} prop
     */
    function _setProp(obj, prop) {
        obj[prop] = obj[prop] || {};
        return obj[prop];
    }

    // Export
    global[root].setNS = setNS;


})(this);

こういうファイルを最初に読んでおいて、他のファイルでは

(function(global, doc, $, ns, undefined) {
    'use strict';
    ns.setNS('ClassName');

    var Piyo = {
        chick: function() {
            // method Piyo.chick();
        }
    };

    ns.ClassName.Piyo = Piyo;

})(this, this.document, jQuery, this.namespace);

みたいな感じで運用していきます。

また、.setNS()は、namespace.でつないで階層を深くすることも出来ます。 例えばこんな感じ。

ns.setNS('view.Fuga.Hoge');
// ns.view.Fuga.Hoge が確保される

こうすると、例えば他のファイルとかでもviewview.Fugaが宣言されていなくても、viewというオブジェクトが生成され、その中にFugaというobjectが生成されて、さらにその直下にHogeが生成されます。

また、もし他のファイルでview.Fuga.Piyoみたいなものが作られていても、それを上書きすることなく、view.Fuga.Hogeが生成されます。

これでnamespaceでぶつかり合ったり、そんなobjectないよ!って怒られたりすることがだいたいなくなります。

ついでですが、そのファイルがどういう機能を実装してるのかもファイル開いてすぐわかる、気がします。