为什么将javascript命名空间作为函数?

时间:2015-11-12 17:13:58

标签: 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 () { /* some constructor */ };
FOO.Bar.prototype.baz = function () { /* A prototype method on FOO.Bar */ };
...

如您所见,FOO命名空间是一个空函数。是否有任何意义将命名空间声明为空函数?这是滥用OLN模式吗?看起来它可能是工厂模式的开始。命名空间中没有原型方法(例如FOO.prototype.bar = ...)。呼叫FOO()显然什么都不做。有人认识到这种模式吗?

2 个答案:

答案 0 :(得分:1)

命名函数为hoisted - 有效地移动到其封闭范围的顶部。使用命名函数可以在声明命名空间之前进行赋值:

FOO.bar = "bar";
function FOO() {}
console.log(FOO.bar); // bar

与Object文字(或非命名函数)相比:

FOO.bar = "bar";
var FOO = {};
console.log(FOO.bar); // undefined

任何人都不可能计划将成员分配到这样的命名空间,但它可能会发生。

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

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

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}

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

答案 1 :(得分:0)

我通常会以下列方式看到这一点:

var FOO = FOO || {};

这样全球就不会被覆盖。

为什么要声明一个空函数?

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

请查看此内容以获得更好的解释:How is almost everything in Javascript an object?