Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespacing with IIFE in ES6?

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?

like image 756
ma11hew28 Avatar asked Sep 23 '15 18:09

ma11hew28


People also ask

When to use IIFE?

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.

How is Namespacing done in JavaScript?

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.

What is JavaScript Namespacing How and where is it used?

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.

What is global namespace in JavaScript?

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.


1 Answers

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.

like image 73
Bergi Avatar answered Oct 24 '22 05:10

Bergi