为什么要将javascript名称空间作为函数来基础?

为什么要将javascript名称空间作为函数来基础?,javascript,namespaces,javascript-namespaces,Javascript,Namespaces,Javascript Namespaces,我正在阅读一个必须保持匿名的库的源代码,我看到它正在使用一个空函数来设置名称空间。它似乎与对象文字符号(OLN)相似,只是基是一个函数 这是一个声明的例子 /** * Base namespace for FOO library * @name FOO * @namespace */ function FOO(){} FOO.bar = 'bar const..'; FOO.fooFunc = function () { /* code */ }; FOO.Bar = function

我正在阅读一个必须保持匿名的库的源代码,我看到它正在使用一个空函数来设置名称空间。它似乎与对象文字符号(OLN)相似,只是基是一个函数

这是一个声明的例子

/**
 * Base namespace for FOO library
 * @name FOO
 * @namespace
 */
function FOO(){}

FOO.bar = 'bar const..';
FOO.fooFunc = function () { /* code */ };
FOO.Bar = function () { /* some constructor */ };
FOO.Bar.prototype.baz = function () { /* A prototype method on FOO.Bar */ };
...

如您所见,FOO名称空间是一个空函数。将名称空间声明为空函数有什么意义吗?这是对OLN模式的误用吗?看起来这可能是工厂模式的开始。命名空间上没有原型方法(例如,
FOO.prototype.bar=…
)。调用
FOO()
显然没有任何作用。有人认识到这种模式吗?

我通常认为这是通过以下方式实现的:

var FOO = FOO || {};
这样就不会覆盖全局

为什么要声明空函数?

这样,作者就可以向FOO添加方法。这只是一种方法,因为在JavaScript中,包括函数在内的大部分内容都是对象

请查看以下内容以获得更好的解释:

命名函数被有效地移动到其封闭范围的顶部。在声明命名空间之前,使用命名函数可能允许赋值:

FOO.bar = "bar";
function FOO() {}
console.log(FOO.bar); // bar
与对象文字(或非命名函数)相比:

不太可能有人计划将成员分配到这样的名称空间,但这是可能发生的

我能想到的另一个优点是函数可以有一个固有的名称,这对于调试可能很有用

例如,如果名称空间成员具有
名称空间
属性(它们可能没有):

与之相比:

var FOO = {};
FOO.bar = { namespace: FOO };
console.log(FOO.bar.namespace); // Object {bar: Object}

纯粹的推测:有些名称空间也可能使用这样的函数进行初始化。这可能是一个名称空间的示例,它不需要任何初始化,但选择使用函数来实现一致性。

我认为这也是通常的做法。当然,函数是一个对象,但我想知道将名称空间声明为函数是否有任何好处。这两个方面都很好。尽管如此,我不认为库利用了提升的优势。我想它保存了
FOO | |(FOO=function(){})
类型检查模块是否以未知顺序连接到同一作用域中。
function FOO(){}
FOO.bar = { namespace: FOO };
console.log(FOO.bar.namespace); // function FOO(){}
var FOO = {};
FOO.bar = { namespace: FOO };
console.log(FOO.bar.namespace); // Object {bar: Object}