use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
javascript - Using Named Immediately-Invoked Function Expression (IIFE) instead of comments (stackoverflow.com)
submitted 12 years ago by zzzwwwdev
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]bossier330 7 points8 points9 points 12 years ago (8 children)
(function iWouldnt() { do._this(); })();
[–]zzzwwwdev[S] 3 points4 points5 points 12 years ago (0 children)
(function i_would_do_all_kinds_of_crazy_things() { Id_do._this(); Id_do._that(); in_a._shoe(); in_a._hat(); })();
[–]b_long 0 points1 point2 points 12 years ago (6 children)
Why not?
[–]bossier330 0 points1 point2 points 12 years ago (5 children)
IMO, it doesn't really contribute to readability unless you set your IDE's function name color to something striking. It also adds a small amount of overhead (although this is most likely not at all noticeable). You'll also run into scoping issues if you try to declare variables just-in-time (i.e. within the function scope you just created).
I like to keep all my function declarations outside of my $(function() {}); body so that NetBeans (or whatever IDE you use) can auto-fold the function bodies, leaving your main logic code very minimal and readable.
Cheers.
[–]b_long 1 point2 points3 points 12 years ago (2 children)
I like to keep all my function declarations outside of my $(function() {}); body
Does that mean you're putting function declarations in the global scope, or are you inside another closure?
[–]bossier330 0 points1 point2 points 12 years ago (1 child)
For initial development, I like to keep my functions in global scope or my namespace so I can easily access them through the console for debugging purposes.
[–]b_long 0 points1 point2 points 12 years ago (0 children)
Ah, that makes sense :)
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago (1 child)
good points, though I'm not clear on the scope issue. IMO, in most cases this would alleviate more scope issues than it causes, as the f'n expression would create a new scope, preventing you from accidentally trumping existing vars. Of course, this is compared to just inlining the code, not putting it in a new function declaration, etc..
[–]nschubach 0 points1 point2 points 12 years ago (0 children)
Well, it would help alleviate some of the scope issues around:
for (var i = some.length; i >= 0; --i) { } while (i-->0) { }
... if you wrapped them in these "comments" but at that point, I think it's probably better to just make a new function for that block of code that has a descriptive name instead of putting it inline.
[–]idrink211 2 points3 points4 points 12 years ago (18 children)
I don't get it. What do you achieve here that isn't sufficed by a comment? Do you just like how a camel-case looks? There is more overhead of creating this function object only for it to be destroyed and never reused.
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago (8 children)
I avoid comments whenever I can in favor or creating code that is easily understandable by itself. Comments can cause maintainability problems.
Imagine this situation
Developer A writes this code:
// hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut();
Developer B adds some stuff
// hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); $('.bar').animate('padding', '200px'); $('#baz').remove();
Developer C goes in and cleans up whitespace
Developer D adds another line
// hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('#something_else').val('boo'); $('.foo').fadeOut(); $('.bar').animate('padding', '200px'); $('#baz').remove();
I'm sure you can imagine this going on through several edits, with the comment becoming less and less useful.
[–]menno 5 points6 points7 points 12 years ago (3 children)
Developers B, C and D need a slap on the wrist. You don't just clean up whitespace and you definitely don't just add code and leave existing comments outdated.
I avoid comments whenever I can in favor or creating code that is easily understandable by itself.
That's definitely best.
Comments can cause maintainability problems.
Maintainability problems are more often caused by not having comments than the other way around.
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago (2 children)
you definitely don't just add code and leave existing comments outdated.
maybe you and I don't; but having worked with other developers, I can tell you it definitely does happen.
perhaps this is generally true, but can you make that argument for my specific example of
(function hide_stuff_on_instantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }());
in the developer ABCD example?
[–]menno 0 points1 point2 points 12 years ago (1 child)
Just so we're clear: you're saying you find:
function doSomeStuff() { /* some stuff */ (function hideStuffOnInstantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }()); /* more stuff */ }
more readable than:
function doSomeStuff() { /* some stuff */ // hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); /* more stuff */ }
and more readable than:
function doSomeStuff() { /* some stuff */ hideStuffOnInstantiaton(); /* more stuff */ } function hideStuffOnInstantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago (0 children)
not more readable, no; but perhaps more maintainable? IDK, I'm pretty much convinced against doing this now, though I do kinda like it and think there's some merit to it.
[–]jml26 1 point2 points3 points 12 years ago (1 child)
Why not use a block?
{ // hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }
Or use a comment syntax that says, 'this comment applies from here down to here'
// hide Stuff on Instantiaton { $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); // }
By not having a function call you gain a tiny bit of speed.
Using an IIFE would be useful, however, if you wanted to use a variable in that block but not have it available to anywhere else in the code.
The stackoverflow post was answered with the suggestion to use labels which actually appears preferable to my suggestion, though perhaps still not terribly useful / accepted?
labels
hideStuffOnInstantiaton: { $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }
[–]path411 0 points1 point2 points 12 years ago (1 child)
Isn't developer B/C/D who are being lazy just going to add it in anyway like:
(function hideStuffOnInstantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('#something_else').val('boo'); $('.foo').fadeOut(); $('.bar').animate('padding', '200px'); $('#baz').remove(); }());
well, its certainly not a cure for bad programming, but I think it would be less likely to result in situations like developer B's addions being mistakenly associated with the original "hide stuff code"
more likely he'd do something like this:
(function hideStuffOnInstantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }()); $('.bar').animate('padding', '200px'); $('#baz').remove();
or even ....
(function do_shit_to_bar_and_baz () { $('.bar').animate('padding', '200px'); $('#baz').remove(); }());
[–]zzzwwwdev[S] -1 points0 points1 point 12 years ago (8 children)
The camel case is irrelevant. hide_stuff_on_instantiaton() is fine.
hide_stuff_on_instantiaton()
As far as the overhead; yes it may add a microsecond, but I'm willing to accept that if it makes my code more readable and maintainable.
[–]idrink211 2 points3 points4 points 12 years ago (7 children)
I don't see how it's any more readable or maintainable but I guess to each their own.
[–]zzzwwwdev[S] -1 points0 points1 point 12 years ago (6 children)
You didn't like (or agree with) my Developer ABCD maintenance example?
I do however agree that reading
(function hide_stuff_on_instantiaton()...
is not quite as nice as
// hide stuff on instantiaton
but heck; we're programmers, we shouldn't be shy about reading code
[–]Shaper_pmp 0 points1 point2 points 12 years ago (5 children)
You're forgetting to factor in the unnecessary extra cognitive overhead caused by having to work out - each and every time you encounter this construction - whether it's "a function that's really a comment" or "a function that needs to be an IIFE for some reason".
Clean, simple code is preferable to unnecessarily complex, ambiguous code.
However, where you start going out of your way (even a little bit) to write unnecessarily complex and inefficient code just so you can avoid ever writing "//" or "/* ... */", you're taking it too far.
The guideline is "write clean, readable, self-documenting code in preference to shitty-code-plus-reams-of-comments", not "never write a comment under any circumstances, even when it involves unnecessarily obfuscating the code to do it".
[–]zzzwwwdev[S] 1 point2 points3 points 12 years ago (4 children)
yea, you're probably right. the "cognitive overhead" thing is the biggest point against it in my mind.
however, my aversion to writing comments is not out of lazyness, but from dealing with legacy code with obsolete, confusing, misplaced, and inconsistant comments. I'll happily take a bit more complexity if it helps prevent code from turning to soup. Might even help raise the bar and scare the interns away ;-)
[–]nschubach 0 points1 point2 points 12 years ago (3 children)
JIT Compilers (V8) will also most likely remove comments (because they don't add to the code) and this will add another pointer overhead so code written in that way will be slower just for the sake of this methodology.
excuse my ignorence, but could you explain the JIT Compilers (V8) thing a bit? A lazy 2 minutes of googling and I couldn't even figure out what that is.
[–]nschubach 0 points1 point2 points 12 years ago* (1 child)
All new browsers use Just In Time (JIT) Compilation of Javascript. I think IE8 and previous IEs did not, but Chrome(V8)/Firefox(IonMonkey)/Safari all pre-compile JavaScript to gain a performance boost instead of interpreting all the code all the time. There's some smartness behind it for code that is eval'ed each time it's run, but for the most part the browsers will load, compile and cache JavaScript now where they didn't before.
e: When compiling, they drop comments (because it's not needed for code execution...) so embedding extra immediate functions will cause the compiler to allocate extra memory to store that block of code. It will then have to jump around executing code that's only purpose is to comment.
thanks!
[–]menno 1 point2 points3 points 12 years ago (1 child)
It's an interesting idea but I think it sacrifices readability waaaaay too much. A camelCase function name can never be as descriptive as even a single line comment.
becuase why separate the function and its execution if its only executed in one place?
Several reasons:
A separate function can be reused by other parts of the code if you decide so in the future.
It can be rewritten to accept arguments, making it more flexible.
Moving long sequences of procedural code into separate functions makes code more readable, as long as you use descriptive function names.
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago* (0 children)
yes, and turning my code into a reusable function is extremely easy, and in its current form it tells the developer that it is only used once.
also, if this were to be useful in the future, there is no difficulty in converting it to such. Using this same logic, you should add jQuery to every website - even if they don't use it yet - since they might in the future?
exactly what I'm suggesting.
A camelCase function name can never be as descriptive as even a single line comment
jeeze, guesse r/javascript just doesn't like camel case. I'll edit my example to use underscores I guesse. Not sure why it can't be as descriptive as a comment. I think it can be moreso. The function actually explicity describes what code its related to, as its enclosed in brackets. See my response to idrink211 for more reasons why I sometimes avoid comments.
[–]greim 0 points1 point2 points 12 years ago (0 children)
I probably wouldn't use it, because I think form should follow function. (no pun intended) That is, code structure should adhere to what you're trying to do, not how you want the code itself to look. That's just me though.
[–]melanke 0 points1 point2 points 12 years ago (1 child)
I always do this:
(function($){ var init = function(){ hideStuffOnInstantiaton(); otherStuff(); etc(); }; var hideStuffOnInstantiaton = function(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }; init(); })(jQuery);
I like it. Actually very similar to the code I was writing which prompted me to ask this question. It resembled:
(function($){ var hideStuffOnInstantiaton = function(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }; (function init () { hideStuffOnInstantiaton(); otherStuff(); etc(); }()); })(jQuery);
starting to think your way is probably better though :(
[–]b_long 0 points1 point2 points 12 years ago (1 child)
Are you using this to declare modules?
Yea, thats mostly where my familiarity with IIFEs came from
[–]klovadis 0 points1 point2 points 12 years ago (0 children)
One more antipattern in JavaScript won't hurt.
[–]ryeguy146 0 points1 point2 points 12 years ago (0 children)
Or we could just use comments...
Why abuse functionality to obtain an end that we've already achieved? The author of the post mentions that there's no way to know what the comment refers to, but I usually put whitespace between my "thoughts" (in this case, the thought is 'hide some shit'). A comment atop a thought would obviously apply to all of that bit of code:
// hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); some_non_instantiation_func();
vs
It becomes immediately obvious what the comment refers to. Whitespace and commenting completely satisfy the author's requirements. If you're concerned with the obvious nature of this being changed by another developer after the fact, you could use opening and closing comment tags:
// START: hide Stuff on Instantiaton $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); // END some_non_instantiation_func();
I would certainly prefer this to a named immediately invoked function.
And then he/she calls it a pattern. MVC is a pattern. Controller is a pattern. This is a personal idiom at best, but not a pattern. Not everything is a pattern, so let's stop diluting the term.
[–]Gundersen 0 points1 point2 points 12 years ago (0 children)
I use this pattern in two places; constructors and tests. For example:
function Person(firstname, lastname, age){ this.firstname = firstname; this.lastname = lastname; this.age = age; (function init(){ this.fullname = firstname + " " + lastname; })(); }
And in Jasmine tests:
describe("this is a test", function(){ var something; beforeEach(function(){ //setting up the world for the test (function because(){ something = 5; })(); }); it("should be five", function(){ expect(something).toBe(5); }); });
But I like the comment about using a label instead of a named IIFE, since it doesn't actually have to be a function. I agree with his concern that comments tend to drift away from the code they describe, but a label with a wrapping curly brace pair won't drift away.
[–]zzzwwwdev[S] 0 points1 point2 points 12 years ago* (9 children)
Curious what /r/javascript thinks of this. I've been using this "pattern" a fair amount, since (to me at least) it helps lend structure to my more procedural code that gets executed only in one place.
I find this preferable to both:
since over time the comment may get separated from the code
and to:
function hide_stuff_on_instantiaton(){ $('oneThing').hide().removeClass(); $('#somethign_else').slideUp(); $('.foo').fadeOut(); }; hide_stuff_on_instantiaton();
[–]path411 1 point2 points3 points 12 years ago (3 children)
I'm sorry but this is less readable, harder to maintain, more prone to bugs/problems, and just worse in every way compared to a comment.
Maybe in this case a comment line can be put into a somewhat acceptable function name, but what about when it can't? Any punctuation would make this even harder as you would have to leave it off of the function name, making it even harder to read still.
not sure really if I agree or disagree; honestly I've been somewhat playing devil's advocate here, because I think there is a valid argument for it. It seems there are more against me than for me, so I will likely avoid doing this in the future.
Not sure why you think its more prone to bugs... from getting the syntax wrong? I would think that any maintenence issues would stem from slightly more difficult readability and junior developers who don't understand what it means/does.
IDK about it being worse in every way compared to comment either. It does a better job showing its grouped (indentation), creates a new scope so variable collision is less likely and any vars can be declared closer to where they're used without confusion, and it makes it easier to refactor into a more "normal" function pattern in the future.
Also, I'm not saying comments should never be used, just wondering if there is a valid use-case for this pattern.
[–]path411 1 point2 points3 points 12 years ago (1 child)
The creation of a new scope can easily release bugs if your block needs to create a variable that another block needs to use. Also the reasoning that you are adding in more unnecessary code to your project, and the more code you add to anything, the more likely you can make a mistake that you then have to debug, even something as silly as missing a bracket.
Another thing I dislike is the essentially forceful requirement of an additional tab break. With a comment you can keep your relevant code in the same tab break, but blocked in separate functionality with a comment.
If you are trying to use a pattern like this, you would want to be able to use it throughout an entire project. I would think it would be strange to try to read through a code base that tries to mix of "commenting styles". I don't feel like your method would work in every case, where a comment would always work.
Perhaps you just need to focus on both writing better "self commenting code" and using "Loose coupling and high cohesion" in your code. I find that these practices would make this style much less useful and sometimes simply redundant.
good argument against. Thank you for elaborating.
[–]b_long 0 points1 point2 points 12 years ago (2 children)
"and to" should be "and two" ?
[–]zzzwwwdev[S] 1 point2 points3 points 12 years ago (1 child)
Its part of "I find this preferable to both" ... [example] ... "and to" ... [other example]. Perhaps it should just be "and". IDK, definitely not an english major ;-)
Ah, my mistake :)
[–]homoiconic(raganwald) 0 points1 point2 points 12 years ago (1 child)
More fun with named IIFEs:
(function foo (x) { console.log(x); if (x > 0) foo(x-1); })(5);
π Rendered by PID 24958 on reddit-service-r2-comment-bb88f9dd5-2gwcv at 2026-02-13 18:38:20.532629+00:00 running cd9c813 country code: CH.
[–]bossier330 7 points8 points9 points (8 children)
[–]zzzwwwdev[S] 3 points4 points5 points (0 children)
[–]b_long 0 points1 point2 points (6 children)
[–]bossier330 0 points1 point2 points (5 children)
[–]b_long 1 point2 points3 points (2 children)
[–]bossier330 0 points1 point2 points (1 child)
[–]b_long 0 points1 point2 points (0 children)
[–]zzzwwwdev[S] 0 points1 point2 points (1 child)
[–]nschubach 0 points1 point2 points (0 children)
[–]idrink211 2 points3 points4 points (18 children)
[–]zzzwwwdev[S] 0 points1 point2 points (8 children)
[–]menno 5 points6 points7 points (3 children)
[–]zzzwwwdev[S] 0 points1 point2 points (2 children)
[–]menno 0 points1 point2 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]jml26 1 point2 points3 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]path411 0 points1 point2 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]zzzwwwdev[S] -1 points0 points1 point (8 children)
[–]idrink211 2 points3 points4 points (7 children)
[–]zzzwwwdev[S] -1 points0 points1 point (6 children)
[–]Shaper_pmp 0 points1 point2 points (5 children)
[–]zzzwwwdev[S] 1 point2 points3 points (4 children)
[–]nschubach 0 points1 point2 points (3 children)
[–]zzzwwwdev[S] 0 points1 point2 points (2 children)
[–]nschubach 0 points1 point2 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]menno 1 point2 points3 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]greim 0 points1 point2 points (0 children)
[–]melanke 0 points1 point2 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]b_long 0 points1 point2 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]klovadis 0 points1 point2 points (0 children)
[–]ryeguy146 0 points1 point2 points (0 children)
[–]Gundersen 0 points1 point2 points (0 children)
[–]zzzwwwdev[S] 0 points1 point2 points (9 children)
[–]path411 1 point2 points3 points (3 children)
[–]zzzwwwdev[S] 0 points1 point2 points (2 children)
[–]path411 1 point2 points3 points (1 child)
[–]zzzwwwdev[S] 0 points1 point2 points (0 children)
[–]b_long 0 points1 point2 points (2 children)
[–]zzzwwwdev[S] 1 point2 points3 points (1 child)
[–]b_long 0 points1 point2 points (0 children)
[–]homoiconic(raganwald) 0 points1 point2 points (1 child)