What is an IIFE?
(function() { console.log('test'); })();
In old versions of JavaScript, variables had to be scoped to the nearest function (rather than the nearest block) so IIFE where often used for namespacing: var $ = (function() { this.version = '1.2.3'; })();
$.version; // 1.2.3
This worked because the function would be immediately invoked upon interpretation, scoping it's contents to itself (aliased by the variable name).A proper example of IIFE for lexical scoping would be something like this:
var numbers = "";
(function(){
for (var i=0; i<5; i++) {
numbers += i + " ";
}
})();
console.log(i) //undefined
Nowadays of course you could just use let instead of varYour code snippet would kind of work as expected if used as a constructor. As in:
var $ = function() { this.version = '1.2.3'; };
var obj = new $;
console.log(obj.version); //1.2.3
Of course that is not a IIFE.Ah...brings me back to my SO days...
var $ = new (function() { this.version = '1.2.3'; })();
console.log($.version); // '1.2.3'
EDIT:
Or if you really want to abuse the spec var $ = (function() { if (!(this instanceof arguments.callee)) return new arguments.callee(); this.version = '1.2.3' })();
console.log($.version); // '1.2.3' var $ = (function(){ this.version = '1.2.3'; return this; }).call({})
console.log($.version); //1.2.3
But that's not quite as ugly so I guess I lose some points.(function() { alert('swiggity swooty'); })();
It's a really neat pattern imo, I remember it fondly from my JS heavy days :)
According to this[1] exchange on Stack Overflow, the IIFE is used by TypeScript because of other scoping issues (specifically protecting class properties before instantiation and defining interfaces).
[0] https://yakovfain.com/2015/06/30/the-private-in-typescript-i...
[1] https://stackoverflow.com/questions/56086411/why-does-typesc...
(async () => { console.log(await 'hello world') })()