我经常遇到将所有JavaScript放在namespace
结构中的网站:
namespaces = { com : { example: { example.com's data} }
然而,相对于其他命名空间框架安全地设置它似乎需要相对大量的代码(定义为> 2行)。我想知道是否有人知道这样做的简洁方法?此外,是否有相对标准/一致的结构方式?例如,com
命名空间是直接附加到全局对象,还是通过命名空间对象附加?
[编辑:哎呀,显然{com = { ... } }
无法完成任何接近我的意图,感谢Shog9指出这一点。]
答案 0 :(得分: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() { /* ... */ }
};
})();
......这是恕我直言,相当简洁。
答案 1 :(得分:12)
这是Peter Michaux在Javascript Namespacing上发表的一篇有趣的文章。他讨论了3种不同类型的Javascript命名空间:
我不会抄袭他在这里说的话,但我认为他的文章非常有用。
彼得甚至指出,其中一些还有性能考虑因素。我认为这个话题很有意思,考虑到新的ECMAScript Harmony计划已经放弃了4.0的命名空间和包装计划。答案 2 :(得分:6)
我尝试遵循雅虎惯例,即在全局范围内制作单个父对象以包含所有内容;
var FP = {};
FP.module = {};
FP.module.property = 'foo';
答案 3 :(得分:5)
为了确保不覆盖现有对象,您应该这样:
if(!window.NameSpace) {
NameSpace = {};
}
或
var NameSpace = window.NameSpace || {};
这样,您可以将它放在应用程序/网站中每个文件的顶部,而不必担心覆盖命名空间对象。此外,这将使您能够单独为每个文件编写单元测试。
答案 4 :(得分:3)
YUI library库具有使用您可能认为更可取的函数处理命名空间的代码。其他图书馆也可以这样做。
答案 5 :(得分:1)
作为点或下划线的替代方法,您可以使用美元符号字符:
var namespaces$com$example = "data";
答案 6 :(得分:1)
我也喜欢这个(source):
(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/>';
答案 7 :(得分: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());
&#13;
或没有明确的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);
&#13;
或者不使用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);
&#13;
使用RegExp
或Object
构造函数将名称属性添加到计数器变量和其他常用名称,然后使用hasOwnProperty
测试进行检查:
var foo = RegExp(/bar/);
/* Add property */
foo.name = "alpha";
document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "	");
/* Check type */
if (foo.hasOwnProperty("name"))
{
document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "	");
}
/* 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, "	");
}
else
{
/* Fallback to atomic value */
counter = 0;
}
&#13;
DOM使用以下约定来命名HTML和SVG Element接口定义:
JavaScript核心使用原型将toString
方法命名为一种简单的多态形式。
<强>参考强>