JavaScript:命名空间

5

我目前在Javascript中使用以下模式创建命名空间和单例对象:

var Namespace = function () {

    var priv = {
        privateVar1: '',
        privateVar2: '',
        privateFunction1: function () {
            //do stuff
            [...]
        },
        [...]
    };

    var pub = {
        publicVar1: '',
        publicFunction1: function () {
                //do stuff with private functions and variables
                priv.privateVar1 = priv.privateFunction1(pub.publicVar1);
            [...]
        },
        [...]
    };

    return pub;
}();

我希望你能理解这个想法。你认为有什么更加清晰或更好的创建命名空间的方法(请解释原因)?


请参考以下链接:https://dev59.com/HFjUa4cB1Zd3GeqPU9OQ(新问题更清晰明了) - Tim Abell
3个回答

5
事实上,这完全是关于语义的。如果你将代码拆分成多个文件,并计划使用一个通用的命名空间,那么像这样做会更容易一些:
我喜欢这种方法的原因是它更加模块化,可以将代码拆分成多个文件,然后轻松地将它们压缩到一个文件中,而不会出现依赖问题(除非你的命名空间函数相互依赖)。
这种方法的缺点是,如果使用不当,有时可能会感觉有点混乱——我想这也适用于任何东西。
在您的命名空间文件中:
var Namespace = {};

在使用命名空间的其他JavaScript文件中
var Namespace = Namespace === undefined ? {} : Namespace;

Namespace.stuff = function () {
    var private = 'foo';
    function private_func() {
    };

    this.public = 'bar';
    this.public_func = function () {
    }
};

一些实际应用如下:

GUI.js

// Some general GUI
var GUI = {
    'MAX_WIDTH': $(window).width(),
    'MAX_HEIGHT': $(window).height()
};

Toolbar.js

GUI.Toolbar = function (id) {
    var self = this;

    function init_visuals() {
        $(id).click(function () {
            self.alert_broken();
        });
    };

    function initialize() {
        init_visuals();
    };

    this.alert_broken = function () {
        alert('Broken!');
    };

    initialize();
};

Menu.js

GUI.Menu = function () {
}; GUI.Menu.prototype = new GUI.Toolbar();

现在,单例模式——这是另一个完全不同的争议话题。

我认为你的例子有问题。"private"和"public"不能用作变量名,因为它们是保留字:http://javascript.about.com/library/blreserved.htm。其次,"public"和"public_func"都无法访问。 - Tim Büthe
他可能没有考虑到这一点 :) 你错了,public和public_func可以通过Namespace.stuff.public和Namespace.stuff.public_funct访问。感谢Justin,我最喜欢你的方法。也谢谢你Tim,你的例子可以与其他模式结合使用,非常有用。 - Kaze no Koe

0

我认为你的例子很好,整个问题大多是关于口味的。然而,我会这样写:

var NAMESPACE = {

    publicVar1: '', 
    publicFunction1: (function(){

        var privateVar1 = '';
        var privateVar2 = '';
        function privateFunction1 () {
            //do stuff
            //[...]
        };

        return function(){
            //do stuff with private functions and variables
            priv.privateVar1 = priv.privateFunction1(pub.publicVar1);
        }
    })()
}

首先,命名空间应该全部大写,就像Douglas Crockford建议的那样,也可以从YAHOO中看到。
其次,我直接创建了NAMESPACE及其属性,而不是通过匿名函数。但是,我在一个匿名函数中创建了publicFunction1函数,这样我就可以在其中定义私有函数和变量。这与你的示例略有不同,因为作用域甚至更小。优点是,同一命名空间内的其他函数可以使用相同的变量名。缺点是,其他函数与该函数不共享相同的变量 :-)

0
这很不错,但最好将私有变量声明为命名空间中的局部变量,而不是使用一个对象priv。优点:代码更少,压缩器可以缩小变量名称。在这里尝试压缩您的代码:http://dean.edwards.name/packer/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接