Using .call()
changes the context of the IIFE to the this
value of the parent scope.
The first this
will be [object Window]
, the global scope in browser environments:
(function () {
console.log(this);
})();
The second, will be the exact same:
(function () {
console.log(this);
}).call(this);
The difference is that in ECMAScript 5's strict mode
, the first example this
will be undefined:
(function () {
'use strict';
console.log(this); // undefined
})();
However when using Strict Mode and .call(), this is again the global scope with the correct this
context:
(function () {
'use strict';
console.log(this);
}).call(this);
Here's a jsFiddle showing this. The main difference is that the normal
IIFE loses it's this
context, some CommonJS platforms evaluate files with a specific this
.
CoffeeScript does this to ensure that your code has the same this
context as the scope where it's placed (the parent scope) - because functions don't normally inherit their this
object from the surrounding context.
Using the pattern(s) above, you should wrap your function logic in there to avoid placing all your code in the global scope and having variable/naming conflicts, to which you can then create things such as Modules and return only the APIs that you need, for instance:
var Module = (function () {
'use strict';
return {
someMethod: function () {
// do something
}
}
})();
// call it:
Module.someMethod();
Each function creates it's own scope, so wrapping your blocks of code in these will protect your variable/function names from conflicting with eachother. We can also access "private" methods from within these closures:
var Module = (function () {
'use strict';
var _privateMethod = function () {};
return {
someMethod: function () {
_privateMethod();
}
}
})();
We would do this when we don't want the methods to be publicly accessible by our users too.