Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I define a JavaScript 'namespace' to satisfy JSLint?

Tags:

I want to be able to package my JavaScript code into a 'namespace' to prevent name clashes with other libraries. Since the declaration of a namespace should be a simple piece of code I don't want to depend on any external libraries to provide me with this functionality. I've found various pieces of advice on how to do this simply but none seem to be free of errors when run through JSLint (using 'The Good Parts' options).

As an example, I tried this from Advanced JavaScript (section Namespaces without YUI):

"use strict"; if (typeof(MyNamespace) === 'undefined') {     MyNamespace = {}; } 

Running this through JSLint gives the following errors:

Problem at line 2 character 12: 'MyNamespace' is not defined. Problem at line 3 character 5: 'MyNamespace' is not defined. Implied global: MyNamespace 2,3 

The 'Implied global' error can be fixed by explicitly declaring MyNamespace...

"use strict"; if (typeof(MyNamespace) === 'undefined') {     var MyNamespace = {}; } 

...and the other two errors can be fixed by declaring the variable outside the if block.

"use strict"; var MyNamespace; if (typeof(MyNamespace) === 'undefined') {     MyNamespace = {}; } 

So that works, but it seems to me that (since MyNamespace will always be undefined at the point it is checked?) it is equivalent to the much simpler:

"use strict"; var MyNamespace = {}; 

JSLint is content with this but I'm concerned that I've simplified the code to such an extent that it will no longer function correctly as a namespace. Is this final formulation sensible?

like image 247
Matthew Murdoch Avatar asked Feb 20 '10 10:02

Matthew Murdoch


People also ask

Does JavaScript support namespace?

JavaScript does not provide namespace by default. However, we can replicate this functionality by making a global object which can contain all functions and variables.

What is the global namespace in JavaScript?

The global namespace is the top space of Javascript that contains the variables. In a browser, it's known as the window.

What is namespace in web development?

Namespace is a context for identifiers, a logical grouping of names used in a program. Within the same context and same scope, an identifier must uniquely identify an entity. In an operating system a directory is a namespace.


2 Answers

Don't take JSLint's word as gospel. Much of what it says is sensible, but it also comes with a lot of Crockford's personal dogma attached. In particular I don't always agree with him about the best place for var.

"use strict"; if (typeof(MyNamespace) === 'undefined') {     MyNamespace = {}; } 

That one's no good; JSLint is correct to complain about the implied global. 'use strict' requires you don't imply globals.

"use strict"; if (typeof(MyNamespace) === 'undefined') {     var MyNamespace = {}; } 

That's fine. The var is hoisted so MyNamespace is present and set to undefined on entering the code block. So you could do that test as (MyNamespace===undefined) even without the typeof operator's magic ability to let you refer to variables that don't exist.

The other way is to use the unambiguous in operator (which is the only way to distinguish between an absent property one that is present but set to undefined). For the case of globals in a normal browser script, you can use it against the global window object:

'use strict'; if (!('MyNamespace' in window)) {     window.MyNamespace = {}; } 

(JSLint doesn't like that either, as ‘assume a browser’ doesn't seem to define window for some unfathomable reason. Hey ho.)

like image 149
bobince Avatar answered Nov 14 '22 09:11

bobince


You can try a much shorter version:

var MyNamespace = MyNamespace || {}; 

This should be valid in JSLint, even in strict mode, using the name if it already exists and creating it if it doesn't, as best a namespace in JavaScript can be expected to work.

like image 21
Ryan Avatar answered Nov 14 '22 09:11

Ryan