如何在JavaScript中创建命名空间,使我的对象和函数不被其他同名对象和函数覆盖?我使用了以下方法:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

有没有更优雅或更简洁的方式来做到这一点?


当前回答

示例:

var namespace = {};
namespace.module1 = (function(){

    var self = {};
    self.initialized = false;

    self.init = function(){
        setTimeout(self.onTimeout, 1000)
    };

    self.onTimeout = function(){
        alert('onTimeout')
        self.initialized = true;
    };

    self.init(); /* If it needs to auto-initialize, */
    /* You can also call 'namespace.module1.init();' from outside the module. */
    return self;
})()

你可以声明一个局部变量,就像self和assign local。onTimeout如果你想要它是私有的。

其他回答

我创建的命名空间是受到Erlang模块的启发。这是一种非常实用的方法,但这就是我最近编写JavaScript代码的方式。

它为闭包提供全局名称空间,并在闭包中公开已定义的集合函数。

(function(){

  namespace("images", previous, next);
  // ^^ This creates or finds a root object, images, and binds the two functions to it.
  // It works even though those functions are not yet defined.

  function previous(){ ... }

  function next(){ ... }

  function find(){ ... } // A private function

})();

我写了另一个命名空间库,它的工作方式有点像其他语言中的包/单元。它允许你创建一个JavaScript代码包,并从其他代码中引用这个包:

文件hello.js

Package("hello", [], function() {
  function greeting() {
    alert("Hello World!");
  }
  // Expose function greeting to other packages
  Export("greeting", greeting);
});

文件Example.js

Package("example", ["hello"], function(greeting) {
  // Greeting is available here
  greeting();  // Alerts: "Hello World!"
});

页面中只需要包含第二个文件。它的依赖项(本例中的文件hello.js)将自动加载,从这些依赖项导出的对象将用于填充回调函数的参数。

你可以在Packages JS中找到相关的项目。

有没有更优雅或更简洁的方式来做到这一点?

是的。例如:

var your_namespace = your_namespace || {};

然后你就可以

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}

我喜欢Jaco Pretorius的解决方案,但我想通过将“this”关键字指向模块/名称空间对象来使其更有用。 我的煎锅版本:

(function ($, undefined) {

    console.log(this);

}).call(window.myNamespace = window.myNamespace || {}, jQuery);

我最近最喜欢的图案是这样的:

Var命名空间=(函数(){ //暴露给公众 返回{ internalA, c: internalC } //所有私有 /** *完整的JSDoc * / 函数internalA() { / /…… } /** *完整的JSDoc * / 函数internalB() { / /…… } /** *完整的JSDoc * / 函数internalC() { / /…… } /** *完整的JSDoc * / 函数internalD() { / /…… } }) ();

当然,return可以在后面,但是如果后面只有函数声明,那么就更容易看到名称空间是关于什么的,以及暴露了什么API。

在这种情况下使用函数表达式的模式导致不遍历整个代码就无法知道公开了哪些方法。