Apparently, ES6 doesn't need namespacing because each file is a separate module.
But then, how do I avoid global namespace interference?
For example, Babel compiles my scripts/main.js
file by merely replacing const
with var
.
var alert = 'This line doesn\'t do anything.'
window.alert(alert)
A namespace (named ANS
below) with an IIFE prevents name collisions:
const ANS = (function () {
const alert = 'This works'
window.alert(alert + '.')
return {alert: alert + ' too.'}
})()
alert(ANS.alert)
Adding properties to the namespace ANS
is cleaner than adding them to the global namespace, window
, or this
. And, the IIFE provides further encapsulation.
So, isn't the second way, i.e., creating a custom namespace with an IIFE, better than the first? If so, is there a newer/nicer way of doing this in ES2015? Why doesn't Babel do this for me?
You can use IIFEs to prevent global variables' definition issues, alias variables, protect private data, and avoid conflicts of using many libraries that export the same object name.
JavaScript by default lacks namespaces however, we can use objects to create namespaces. A nested namespace is a namespace inside another namespace. In JavaScript, we can define a nested namespace by creating an object inside another object.
Namespace refers to the programming paradigm of providing scope to the identifiers (names of types, functions, variables, etc) to prevent collisions between them. For instance, the same variable name might be required in a program in different contexts.
In JavaScript, it is nothing but a single global object which will contain all our functions, methods, variables and all that. Here ' MYAPPLICATION ' is acted as a JavaScript namespace and the only global object which contains all other items.
Apparently, ES6 doesn't need namespacing because each file is a separate module.
Not exactly. Each module does have its own scope, that is correct, but not every file is a module. There still are scripts in ES6 that work just like those from ES5, and are executed in the global scope.
In those scripts, you still need to avoid globals as much as you can, typically by not declaring/assigning any variables or by wrapping your "module" in an IEFE to give it a separate variable scope.
Is there a newer/nicer way of doing this in ES6?
You can use a block and lexical variable declarations (let
, const
, function
):
{
const msg = 'This line doesn\'t do anything.'
window.alert(msg);
}
// msg is not defined here
Or you can use an arrow function in your IEFE, which allow you to use this
to refer to the global object without needing to use .call(this)
):
(() => {
var msg = 'This line doesn\'t do anything.'
window.alert(msg);
})();
But then, how do I avoid global namespace interference, or name collisions?
In ES6 modules, there is nothing global except the builtin objects and maybe the global object. Avoid modifying them.
And of course you will need to take care about collisions between module names - how to do that should be explained in the docs for the resolver mechanism of your module loader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With