Immediately-Invoked Function Expression (2010)
benalman.com16 points by motorest 4 days ago
16 points by motorest 4 days ago
Reminds me of this post https://maxgreenwald.me/blog/do-more-with-run
I now reach for this a lot to allow me to write expression oriented programs in JS
Yeah I remember reading this post, thinking "whatever" about it, and then finding myself implementing and using it regularly-ish.
Usually I use it to encapsulate a complicated initialisation of a variable, where some mutation is needed/easier. I still want colocation for readability, but I dont want intermediate variables in the scope or to declare the variable as mutable
This blog post is referenced by Mozilla's page on IIFE.
I frequently reach for IIFE when I use switch/case. It's a very convenient (if maybe a bit weird looking) way of turning a statement into an expression. In other words, `return 1` instead of `foo = 1; break` for a trivial example.
Yes, this is works really well even outside of JS.
In languages where more control flow constructs are expressions (if, match, try-catch) I don't need this, except if you count `run` in Kotlin.
What language are you thinking of?
Missing my favourite when you don't care about a return value, which I personally find less fussy to type and look at (good for confusing Java developers who don't share the fullness of the stack, too):
void function() {
…
}()
Escpecially when I can't be bothered to stop and extract an async function out when there's a sudden need to wait in a non-async context, handy when in the middle of adding features to browser extensions for apps: let $el = document.querySelector(…) // oops, not available yet
void async function() {
let $el = await waitForElement(…)
}()
Edit: documented on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...One of the things I hated most about using JavaScript in that era was the proliferation of long chains of }); or whatever the order was. IIFEs were a major contributor to that.
It's okay to name your functions. Flat is better than nested.
Those infuriate me so much when I need a slight modification to the behavior of a third party library. Leaves no option but forking. There are such better ways to achieve encapsulation in modern JS.
It's not so much about the encapsulation. Since ES6 you can achieve encapsulation more directly through an arbitrary block, such use of curly braces not associated with a loop, condition, or object. This is what older languages like C and SQL call a procedure.
The primary value of IIFE is that it is encapsulation that outputs to a value and data type. For example if an IIFE returns a string then it looks like a function, behaves like a function, but it is a primitive string type.
> There are such better ways to achieve encapsulation in modern JS.
There aren't that many options even in modern JavaScript. You have ES6 modules, store state in a global map, what else?
Classes?
You don’t need a LOT of options. Just at least one that’s better and more extensible than this pattern.
Yarn and pnpm have a `patch` utility and apply patches on install. It's how I fix pain points like this without a full on fork.