Step by step explication of the code
var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
console.log(exports === module); // Writes true into the console
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); // Outputs "I am global"
module.notGlobalFunction(); // Outputs "I am not global"
The following row declares a variable and assigns to it an empty object:
var module = {};
Among other things, it can be also used as namespace to prevent the pollution of the global scope.
The following row declares an anonymous function with a parameter named exports that will be available only inside the scope of the anonymous function itself:
(function(exports){
As already said, into the row above, the var exports is a parameter of the anonymous function it self and as we are going to see, it references (basically creates a local alias) that holds the same content that is inside the var module: this is because in Javascript objects are passed by reference.
The following rows:
exports.notGlobalFunction = function() {
console.log('I am not global');
};
assign a method (= function inside an object) to the notGlobalFunction property crated into the object {} referenced into exports and also stored into the var module.
So, basically, in other words, the part .notGlobalFunction will be a property, or more precisely in this case, will store a method that is going to be owned by both the two object vars, module and exports. So with this code and as a consequence of the above explication (in javascript object are passed by reference) the same property will be also available into the var module too as will be the whole function that it will hold. So after executing the above code both the vars exports and module will store/reference the same object, in fact:
module =
{
notGlobalFunction: function() {console.log('I am not global');}
}
and
export =
{
notGlobalFunction: function() {console.log('I am not global');}
}
and if right after the following code:
exports.notGlobalFunction = function() {
console.log('I am not global');
};
you also do:
console.log(exports === module);
that is a strict comparison of the two objects, you will get true into the console because module and exports are basically storing/referencing the exact same object.
The following row passes to the parameter called exports of the anonymous function above, a reference to the empty object {} that was first stored into the var module with the code into the first row. So the var module here becomes an argument of the anonymous function above:
}(module));
so the object stored into the var module is passed as reference to the var exports, similarly to if we had done:
exports = module;
The rest of the code
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); // Outputs "I am global"
module.notGlobalFunction(); // Outputs "I am not global"
basically aims to demonstrate and compare the different availability and behaviors of global and local scopes/namespaces: the comments already present into the code are self esplicative.
Follows the code snippet:
var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
console.log(exports === module); // Writes true into the console
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); // Outputs "I am global"
module.notGlobalFunction(); // Outputs "I am not global"
IIFE
is more correct. – Opponent