15

我经常遇到将所有 JavaScript 都放在一个namespace结构中的网站,其结构如下:

namespaces = { com : { example: { example.com's data} }

但是,相对于其他命名空间框架安全地设置它似乎需要相对大量的代码(定义为 > 2 行)。我想知道是否有人知道这样做的简洁方法?此外,是否有一种相对标准/一致的方式来构建它?例如,com命名空间是直接附加到全局对象上,还是通过命名空间对象附加?

[编辑:哎呀,显然{com = { ... } }不会完成任何接近我预期的事情,感谢 Shog9 指出这一点。]

4

8 回答 8

19

Javascript 没有独立的命名空间。它具有可以提供解析名称范围的功能,以及可以为给定范围内可访问的命名数据提供帮助的对象。

这是您的示例,已更正:

var namespaces = { com: { example: { /* example.com's data */ } } }

namespaces这是一个被分配了一个对象字面量的变量。该对象包含一个属性:com,一个具有一个属性example的对象: ,一个可能包含有趣内容的对象。

因此,您可以键入类似namespaces.com.example 的内容。somePropertyOrFunctionOnExample一切都会奏效。当然,这也很可笑。您没有分层命名空间,您有一个包含一个对象的对象,该对象包含一个包含您真正关心的东西的对象。

var com_example_data = { /* example.com's data */ };

没有毫无意义的层次结构,这也同样有效。

现在,如果你真的建立一个层次结构,你可以尝试这样的事情:

com_example = com_example || {};
com_example.flags = com_example.flags || { active: false, restricted: true};

com_example.ops = com_example.ops || (function()
    {
       var launchCodes = "38925491753824"; // hidden / private
       return {
         activate: function() { /* ... */ },
         destroyTheWorld: function() { /* ... */ }
       };
    })();

...也就是说,恕我直言,相当简洁。

于 2008-08-16T16:04:18.260 回答
12

这是 Peter Michaux 关于Javascript 命名空间的一篇有趣的文章。他讨论了 3 种不同类型的 Javascript 命名空间:

  1. 前缀命名空间
  2. 单个对象命名空间
  3. 嵌套对象命名空间

我不会抄袭他在这里所说的话,但我认为他的文章信息量很大。

彼得甚至指出其中一些有性能考虑。考虑到新的 ECMAScript Harmony 计划已经放弃了命名空间和打包的 4.0 计划,我认为谈论这个话题会很有趣。

于 2008-08-17T05:31:35.683 回答
6

我尝试遵循 Yahoo 约定,在全局范围内制作单个父对象以包含所有内容;

var FP = {};
FP.module = {};
FP.module.property = 'foo';
于 2008-08-17T10:46:13.347 回答
5

为确保您不会覆盖现有对象,您应该这样做:

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

或者

var NameSpace = window.NameSpace || {};

这样,您可以将其放在应用程序/网站中每个文件的顶部,而不必担心覆盖命名空间对象。此外,这将使您能够单独为每个文件编写单元测试。

于 2008-08-18T14:55:22.313 回答
3

YUI 库库的代码使用您可能会觉得更可取的函数来处理命名空间。其他库也可以这样做。

于 2008-08-16T16:06:03.860 回答
1

作为点或下划线的替代方法,您可以使用美元符号字符:

var namespaces$com$example = "data"; 
于 2008-08-18T01:38:36.340 回答
1

我也喜欢这个(来源):

(function() {
    var a = 'Invisible outside of anonymous function';
    function invisibleOutside() {
    }

    function visibleOutside() {
    }
    window.visibleOutside = visibleOutside;

    var html = '--INSIDE Anonymous--';
    html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
    html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
    contentDiv.innerHTML = html + '<br/><br/>';
})();

var html = '--OUTSIDE Anonymous--';
html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
contentDiv.innerHTML += html + '<br/>';​
于 2009-06-18T21:16:12.787 回答
0

使用对象字面量和this对象或显式名称根据包含函数的局部变量的同级属性进行命名空间。例如:

var foo = { bar: function(){return this.name; }, name: "rodimus" }
var baz = { bar: function(){return this.name; }, name: "optimus" }

console.log(foo.bar());
console.log(baz.bar());

或者没有显式name属性:

var foo = { bar: function rodimus(){return this; } }
var baz = { bar: function optimus(){return this; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

或不使用this

var foo = { bar: function rodimus(){return rodimus; } }
var baz = { bar: function optimus(){return optimus; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

使用RegExporObject构造函数将名称属性添加到计数器变量和其他常用名称,然后使用hasOwnProperty测试进行检查:

 var foo = RegExp(/bar/);
 
/* Add property */
foo.name = "alpha";

document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "&#09;");

/* Check type */
if (foo.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "&#09;");
  }

/* Fallback to atomic value */
else 
  {
  foo = "baz";
  }

var counter = Object(1);

/* Add property */
counter.name = "beta";

if (counter.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["counter", Number(counter), counter.name] + "</pre>").replace(/,/g, "&#09;");
  } 
else 
  {
  /* Fallback to atomic value */
  counter = 0;
  }

DOM 使用以下约定来命名 HTML 和 SVG 元素接口定义:

  • HTML标题元素
  • SVG 标题元素
  • SVGScriptElement
  • HTMLScriptElement

JavaScript 核心使用原型将toString方法命名为简单的多态形式。

参考

于 2012-03-23T23:25:16.507 回答