JavaScript 命名空间声明

3

如何正确声明命名空间?我刚读完《开发大型 Web 应用程序》,作者建议使用以下方式:

if (!window.YourNamespace) {
  YourNamespace = {};
}

看起来很简单..但是我看到所有的JavaScript库都用于声明命名空间和替代方法。有没有标准的方法来做这个?上面的代码有什么问题吗?


目前,JavaScript开发人员更常使用封闭模块格式而非在全局范围定义对象。使用像require.js这样的模块加载器可以帮助解决这个问题。有两种不同的模块格式可供选择:AMD和/或CommonJS,您可以在博客文章Writing Modular Javascript by Addy Osmani中了解更多信息。 - Spoike
7个回答

2

书籍作者提到的命名空间声明方式确实非常好。但是当你需要在多个文件中重复使用它并且命名空间有多个子命名空间时,这可能会变得相当繁琐:

if (!window.Foo) {
  Foo = {};
}
if (!window.Foo.Bar) {
  Foo.Bar = {};
}
if (!window.Foo.Bar.Baz) {
  Foo.Bar.Baz = {};
}
etc...

相反,您应该编写一个简单的函数来为您声明名称空间:

function namespace(ns) {
  var parts = ns.split(/\./);
  var obj = window;
  for (var i=0; i<parts.length; i++) {
    var p = parts[i];
    if (!obj[p]) {
      obj[p] = {};
    }
    obj = obj[p];
  }
}

现在你可以只使用一行代码来声明整个嵌套的命名空间:
namespace("Foo.Bar.Baz");

在ExtJS框架中,Ext.ns()函数基本上就是这样的。我不太了解其他库。

2

我在很多地方看到过这种惯例的使用。

window.YourNamespace = window.YourNamespace || {};

我之前写的内容的简化版本。 - Sven Hecht

0
  var Utils = {
        namespace : function(name) {
                return window[name] = window[name] || {};
        }
  };

或者如果你更喜欢你的方式使用:

if (typeof window.YourNamespace === 'undefined') {
    YourNamespace = {};
}

为什么第二种方式比我上面发布的方式更好?第一种方式是如何工作的?我有点困惑。Utils是命名空间,它是一个由函数组成的关联数组? - at.
抱歉,我应该澄清一下。上面的Utils类更好,因为您可以按如下方式使用它:Utils.namespace("myGreatNewNamespace"); - Sven Hecht
第二种方法更好,因为即使测试 !window.YourNamespace 可以捕获默认情况,但如果存在全局变量 YourNamespace = 1;,它将不会捕获它并覆盖 YourNamespace = 0; 如果您想要未定义,则应始终测试 undefined。在这些情况下,还应使用 === 而不是 ==。 - Sven Hecht

0

在JavaScript中自动命名空间声明非常简单,如下所示:

var namespace = function(str, root) {
    var chunks = str.split('.');
    if(!root)
        root = window;
    var current = root;
    for(var i = 0; i < chunks.length; i++) {
        if (!current.hasOwnProperty(chunks[i]))
            current[chunks[i]] = {};
        current = current[chunks[i]];
    }
    return current;
};

// ----- USAGE ------

namespace('ivar.util.array');

ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);

namespace('string', ivar.util);

ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo); 

试一下:http://jsfiddle.net/stamat/Kb5xY/ 博客文章:http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/


0

在不同的框架之间,没有标准的方法,但它们超越了基础知识,例如 X.Y.Z,如果它们不存在,它将创建该链中的所有对象。


0

bob.js 这样处理命名空间:

bob.ns.setNs('YourNamespace', {

    /*define your members here. e.g.:*/
    method1: function () { /*...*/ }
});


// now, merge another, sub-namespace.
bob.ns.setNs('YourNamespace.YourSubNamespace', {

    method2 function () { /*...*/ }
});

//call methods:
YourNamespace.method1();
YourNamespace.YourSubNamespace.method2();

-1

一些命名空间函数的示例:

namespace = function(ns){
    arr = ns.split(".")
    parent = window

    var temp

    while( ( temp = arr.shift()) !== undefined){
        parent[temp] = parent[temp] || {}
        parent = parent[temp]
    }
}

然后您可以将其用作:

namespace("your.own.namespace")

your.own.namespace.Car= function () {

    this.speed = 30; 

}

这个问题并没有提供其他答案中没有的信息。而且它并没有真正回答这个问题。 - Xaver Kapeller

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