In the olden days of JavaScript, we used IIFEs to avoid polluting the global namespace. Nowadays, we can just use block scopes to achieve the same thing. I'm not sure about the browser support, though, so take that with a grain of salt.
constoutside='foo';// This only works for block-scope variables (i. e. `const` and `let`).{constinside='bar';console.log(outside);'foo'console.log(inside);'bar'}console.log(outside);// 'foo'console.log(inside);// ReferenceError
With that said, an IIFE is pretty much obsolete now that we can declare block-level scopes as such. However, IIFEs are still prevalent because of backwards-compatibility.
Upon your special request, I might write an article that goes more in-depth about each of the use cases you mentioned. I probably should. I hope my time allows it. It's quite an interesting topic. I'll be sure to mention you in my (future) article if so.
That's unless you have top-level await support in your environment (which Node doesn't but the esm package can be configured to provide or if you transpile)
Also, just a side note, I just realized now that top-level await is essentially a glorified way of writing top-level synchronous code. That's kind of strange... ๐ค
You could argue that the following syntax is subjectively easier to grok, because it's explicit about the definition and execution of the async function main. However, there's no technical advantage of one syntax vs the other.
I am a software development engineer in test for Infosys. My job is officially to write automated tests in Selenium Webdriver. I'm also a web developer as a hobbyest
I did find an interesting use case for an IIFE the other day.
I wanted an array of emojis. I got them from EmojiCopy and I copied them as a string. I didn't want however to write them all down one by one to create an array. What I needed instead was a function that is immediately invoked and turns my string into an array. What makes this difficult, is that I can't use split('') because an emoji is technically two characters, not one.
Now granted, I could have saved that IIFE as its own function and then called it, but I don't need to call it more than ones so why make a reference to a function I only need to ever use once?
This is definitely a valid use case for it. I guess the only problem you'll ever face with this approach is readability. At first glance, it isn't really a design pattern you see often. Moreover, the algorithm isn't as straightforward as one may think. Perhaps sprinkling a few comments here and there explaining your rationale and thought processes will help. Other than that, I see nothing wrong with this. ๐
That's because it's an anti-pattern. This is not a valid use case.
An interpreter already executes code, so you don't need to wrap it in a function. Remove the function, and you've got the same output.
If you need to repeat execution, you should define a function with a descriptive name.
In this case, the result will always be the same, and the whole function can be replaced with its output to save on execution time.
An IIFE is still common. It's often used in browser
content extensions or snippets loaded from providers (analytics, ads, ...), because the browser's scope is shared by all active snippets, so we limit the scope.
Yes, you are correct that an IIFE creates its own scope. As a consequence of that, any variable declared inside an IIFE is only visible to its scope.
In the olden days of JavaScript, we used IIFEs to avoid polluting the global namespace. Nowadays, we can just use block scopes to achieve the same thing. I'm not sure about the browser support, though, so take that with a grain of salt.
With that said, an IIFE is pretty much obsolete now that we can declare block-level scopes as such. However, IIFEs are still prevalent because of backwards-compatibility.
Upon your special request, I might write an article that goes more in-depth about each of the use cases you mentioned. I probably should. I hope my time allows it. It's quite an interesting topic. I'll be sure to mention you in my (future) article if so.
The one place where IIFEs can still be useful is surprisingly async/await in Node.
You can't use await outside of async so you end up doing something like:
That's unless you have top-level await support in your environment (which Node doesn't but the
esm
package can be configured to provide or if you transpile)Oh, yeah. How could I forget about that?
Also, just a side note, I just realized now that top-level await is essentially a glorified way of writing top-level synchronous code. That's kind of strange... ๐ค
You could argue that the following syntax is subjectively easier to grok, because it's explicit about the definition and execution of the async function
main
. However, there's no technical advantage of one syntax vs the other.I did find an interesting use case for an IIFE the other day.
I wanted an array of emojis. I got them from EmojiCopy and I copied them as a string. I didn't want however to write them all down one by one to create an array. What I needed instead was a function that is immediately invoked and turns my string into an array. What makes this difficult, is that I can't use
split('')
because an emoji is technically two characters, not one.So I used an IIFE to create my array:
Now granted, I could have saved that IIFE as its own function and then called it, but I don't need to call it more than ones so why make a reference to a function I only need to ever use once?
This is definitely a valid use case for it. I guess the only problem you'll ever face with this approach is readability. At first glance, it isn't really a design pattern you see often. Moreover, the algorithm isn't as straightforward as one may think. Perhaps sprinkling a few comments here and there explaining your rationale and thought processes will help. Other than that, I see nothing wrong with this. ๐
That's because it's an anti-pattern. This is not a valid use case.
An IIFE is still common. It's often used in browser
content extensions or snippets loaded from providers (analytics, ads, ...), because the browser's scope is shared by all active snippets, so we limit the scope.
Well, there's that, too. ๐
Hey, I just want to point out that you can do the same with:
๐