Why base a javascript namespace as a function?

2019-07-13 05:35发布

I was reading the source code of a library, which must remain anonymous, and I see that it's using an empty function to setup the namespace. It appears to be similar to the object literal notation (OLN) except that the base is a function.

Here's an example of the declaration.

/**
 * 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 */ };
...

As you can see, the FOO namespace is an empty function. Is there any point of declaring the namespace as an empty function? Is this a misuse of the OLN pattern? It looks like it may have been the start of a factory pattern. There's no prototype methods on the namespace (e.g. FOO.prototype.bar = ...). Calling FOO() clearly does nothing. Does anyone recognize this pattern?

2条回答
Rolldiameter
2楼-- · 2019-07-13 05:51

I typically see this done in the following manner:

var FOO = FOO || {};

So that the global isn't overwritten.

Why declare an empty function?

This is so the author can then add methods to FOO. It's just one way to do it because in JavaScript most everything, including functions, are objects.

Please review this for a better explanation: How is almost everything in Javascript an object?

查看更多
相关推荐>>
3楼-- · 2019-07-13 06:11

Named functions are hoisted - effectively moved to the top of their enclosing scope. Using a named function could allow assignment before the namespace is declared:

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

Compared to an Object literal (or non-named function):

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

It's unlikely that anybody would plan to assign members to a namespace like this, but it could happen.

The only other advantage I can think of a is that functions can have an inherent name, which may be useful for debugging.

For example, if namespace members had a namespace property (which they probably don't):

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

Compared to:

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

Pure speculation: it's also possible that some namespaces could use a function like this for initialisation. This could be an example of a namespace that does not need any initialisation, but chooses to use a function for consistency.

查看更多
登录 后发表回答