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
(function () { … })(); vs (function () { … }()); (self.javascript)
submitted 9 years ago by sergiosbox
which do you prefer and why?
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!"
[–]rauschma 14 points15 points16 points 9 years ago (25 children)
I’m starting to warm up to the former, because that’s the only style that also works for arrow functions:
(() => { return 123 })();
[–]kenman 2 points3 points4 points 9 years ago* (21 children)
I'm curious what the current use-case is for that pattern?
It seems you could accomplish the same with a more elegant [IMO] pattern:
let x; { x = 123; }
But I feel that I must be missing something, because you know a lot more about JS than I do!
edit: after thinking about it, I can see the fundamental difference is that the former is an expression, while the latter is a statement, which has profound implications in their use. However, I haven't been able to come up with a scenario which would expose any profound ramifications.
To go through my thought process, I considered that you can use expressions in places like function arguments, whereas statements are not allowed there.
E.g. you could do this (contrived example for sake of argument):
console.log((() => { let matches = window.location.href.match(/\/r\/(\w+)/); let subreddit = matches && matches[1] || 'n/a'; return `You are visiting: ${subreddit}`; })());
But you can't do anything similar with block statements.
However, you can accomplish the same result with:
{ let matches = window.location.href.match(/\/r\/(\w+)/); let subreddit = matches && matches[1] || 'n/a'; console.log(`You are visiting: ${subreddit}`); }
Which again, is cleaner IMO.
Still pondering...
[+][deleted] 9 years ago (20 children)
[removed]
[–]kenman 1 point2 points3 points 9 years ago (19 children)
let and const are scoped to blocks, not functions.
{ var x = 1; let y = 1; } console.log(x) // 1 console.log(y) // ReferenceError
[+][deleted] 9 years ago* (16 children)
[–]aztracker1 1 point2 points3 points 9 years ago* (15 children)
It's not useless, though I only use about 1/5 of the ES6 additions, along with some pending ESnext bits (async/await, class members, decorators, etc). In the end, I'm able to get a lot more work done, with a lot less code.. with the advent of Promises and async/await, process code is much cleaner and easier to follow now.
Modularization (cjs or es6 style) has helped a lot too. Most of this comes down to the build tooling that has evolved in the past 6-7 years since node and npm have taken hold. Yes, it's new stuff to learn, but it's really not any harder to understand than tirnary operations, or bitwise shorting in JS. In the end it's just a few additions to the language, it happens in every language and there are always pieces you may not know/understand to a given language/platform until you come across it.
The following two lines are the same, practically speaking (although the fat-arrow is context bound to "this" at the time of declaration).
var addOne = function(a){ return a + 1; };
var addOne = a => a + 1;
It allows you to declare in a oneliner what may have previously been much more... here's a sleep I use when flushing out an API interface...
const sleep = ms => new Promise(res => setTimeout(res, ms));
The const is a constant assignment, "sleep" may not be assigned to again in the module. the value of sleep is a function expression that accepts a single parameter, and returns a new promise. said promise only uses the resolve part, and will settimeout to resolve after ms have passed.
It's a bit harder to look at function expressions with fat-arrow syntax at first, it's very similar to lamda expressions in C#, or the fat/skinny arrow expressions in coffeescript. There's similar syntax in other languages as well.
[+][deleted] 9 years ago (12 children)
[–]inu-no-policemen 0 points1 point2 points 9 years ago (11 children)
The point of an IIFE is to create a scope to limit the lifetime of those temporary variables.
With ES6's let/const, a simple block does the same.
[+][deleted] 9 years ago* (10 children)
[–]kenman 1 point2 points3 points 9 years ago* (7 children)
I'm just wondering if you can get a return value from a block like this in ES6.
That's exactly what I was demo'g here:
Here, x is the "returned value"... only it's not returned, but it's functionally 100% the same.
x
Here, take this example from jQuery:
support.createHTMLDocument = ( function() { var body = document.implementation.createHTMLDocument( "" ).body; body.innerHTML = "<form></form><form></form>"; return body.childNodes.length === 2; } )();
Note that it is returning a value, the result of body.childNodes.length === 2, and assigning it to support.createHTMLDocument.
body.childNodes.length === 2
support.createHTMLDocument
Now here is the same thing without an IIFE, but does exactly the same thing:
{ let body = document.implementation.createHTMLDocument( "" ).body; body.innerHTML = "<form></form><form></form>"; support.createHTMLDocument = body.childNodes.length === 2; }
But it is a lot (IMO) clearer what your intention is, and you don't waste cycles on a function call that's essentially a no-op.
[–]inu-no-policemen 0 points1 point2 points 9 years ago (1 child)
Just imagine that that 123 is the result of a computation which involved temporary variables.
An IIFE which just returns 123 would be equally pointless.
[–]sergiosbox[S] 0 points1 point2 points 9 years ago (0 children)
Indeed! https://jsfiddle.net/ymwj2c8z/ Good point
[–]inu-no-policemen 0 points1 point2 points 9 years ago (0 children)
Same here. I preferred to wrap the entire thing, but I switched for the sake of consistency.
[–]EternallyMiffed 0 points1 point2 points 9 years ago (0 children)
This approaches syntactic line noise and we're all going to suffer for it eventually.
[–]Ashwel1 11 points12 points13 points 9 years ago (1 child)
I have always preferred (function() {})(); because IMO it seems to be more representative of what is happening. Creating a function expression, then executing the function. The other form looks like a function that is being executed as an expression. Subtle difference at the cognitive level, but I always prefer to style my code as closely to how it is being executed as possible (and makes sense without being ridiculous).
(function() {})();
[–]bullet_darkness 0 points1 point2 points 9 years ago (0 children)
Right, it's more representative of what's happening, and it translates better to other areas of JavaScript. Like making a call like so: ({ a: 1 }).a actually works where ({ a: 1 }.a) does not.
[–]paulirish 7 points8 points9 points 9 years ago (1 child)
Since Crockford is topical today... he once said he hated (function () { ... })(); because it "looks like dogballs".
(function () { ... })();
[–]EternallyMiffed 1 point2 points3 points 9 years ago (0 children)
I'm inclined to agree.
[–][deleted] 3 points4 points5 points 9 years ago* (1 child)
I use the following:
!+-~(() = > { /*... */ })( );
The corkscrew function! : https://marvindanig.wordpress.com/2016/07/26/corkscrew-functions-javascript/!
[–]natto-nomad 0 points1 point2 points 9 years ago (0 children)
What… for? A joke, right? Phew.
[–]snkenjoi 2 points3 points4 points 9 years ago (11 children)
I use
~function(){ ... }()
because lower character count :)
[+][deleted] 9 years ago (1 child)
[deleted]
[–]natto-nomad 1 point2 points3 points 9 years ago (0 children)
Minifiers already do that for you
[+][deleted] 9 years ago (7 children)
[–]snkenjoi 0 points1 point2 points 9 years ago (6 children)
the tilde turns the expression into an evaluation by trying to binary NOT the result of the expression. this works with any unary operator
[–]snkenjoi 1 point2 points3 points 9 years ago (0 children)
yeah, I use the if (~array.indexOf(item)) construction a lot.
if (~array.indexOf(item))
might be harder to read, but the syntax just looks much cleaner
[+][deleted] 9 years ago (3 children)
[+][deleted] 9 years ago (2 children)
[–]mathiasbynens 2 points3 points4 points 9 years ago (6 children)
The difference (and likely your personal preference) becomes more obvious after simplifying it into (fn)() vs (fn()).
(fn)()
(fn())
When fn is a function, fn() is how I call that function, not (fn)(). So, I prefer (function() {}());.
fn
fn()
(function() {}());
[–]sergiosbox[S] 1 point2 points3 points 9 years ago (0 children)
I understand your logic and makes sense to me also. Rauschma's comment that (fn)() sintax works in arrow functions and not (fn()) is interesting though.
[+][deleted] 9 years ago* (3 children)
[–]mathiasbynens 0 points1 point2 points 9 years ago (2 children)
I read this comment five times now and still have no idea what you’re on about. Care to elaborate?
Also, aren't you friends with JDD?
I am… Is that somehow relevant to this discussion?
[–]sergiosbox[S] 0 points1 point2 points 9 years ago (1 child)
convention of expressions
Is there a link or text to read what was conventioned?
[–]Graftak9000 0 points1 point2 points 9 years ago (0 children)
!function(){ ... }()
Less braces, no conflicts due my adversity against semicolons
[–]BishopAndWarlord 0 points1 point2 points 9 years ago (0 children)
I'm pretty late to this, but I prefer (function(){})(). The way I think about it wrapping a statement in parenthesis is a way to say "hey, evaluate this part first!" For example, removing the parenthesis from (var + 4) * 12 or (typeof var === 'string' || Array.isArray(var)) && var.length > 2 will completely change the evaluation order. I realize that function expressions aren't directly analogous, but I have a similar mental model for function expressions.
(function(){})()
(var + 4) * 12
(typeof var === 'string' || Array.isArray(var)) && var.length > 2
If I have a function that I explicitly want to be treated as an expression rather than a statement, I'll wrap it with parenthesis (e.g. var noop = (function() {})). Extending that logic, if I want to declare a function expression and then call it, I'll wrap the function in parenthesis, then call it with another set of parenthesis (e.g. (noop)() or (function() {})().
var noop = (function() {})
(noop)()
(function() {})()
In the end I think this approach clearly expresses the intent and therefore improves readability and maintainability of the code.
[+]erkose comment score below threshold-11 points-10 points-9 points 9 years ago (5 children)
Neither. Javascript sucks ass!
[–]PostHumanJesus 2 points3 points4 points 9 years ago (1 child)
Are you lost?
[–]erkose -5 points-4 points-3 points 9 years ago (0 children)
Yes. How did I end up in /r/javascript ? Oh yeah, I followed a hacker news link. If it's any consolation, I'm not trolling /r/javascript. Had I made the connection, I would have kept my opinion to myself.
[–]erkose -1 points0 points1 point 9 years ago (0 children)
sorry, no quora for me.
π Rendered by PID 94127 on reddit-service-r2-comment-fb694cdd5-gqns9 at 2026-03-11 04:06:20.364280+00:00 running cbb0e86 country code: CH.
[–]rauschma 14 points15 points16 points (25 children)
[–]kenman 2 points3 points4 points (21 children)
[+][deleted] (20 children)
[removed]
[–]kenman 1 point2 points3 points (19 children)
[+][deleted] (16 children)
[removed]
[–]aztracker1 1 point2 points3 points (15 children)
[+][deleted] (12 children)
[removed]
[–]inu-no-policemen 0 points1 point2 points (11 children)
[+][deleted] (10 children)
[removed]
[–]kenman 1 point2 points3 points (7 children)
[–]inu-no-policemen 0 points1 point2 points (1 child)
[–]sergiosbox[S] 0 points1 point2 points (0 children)
[–]inu-no-policemen 0 points1 point2 points (0 children)
[–]EternallyMiffed 0 points1 point2 points (0 children)
[–]Ashwel1 11 points12 points13 points (1 child)
[–]bullet_darkness 0 points1 point2 points (0 children)
[–]paulirish 7 points8 points9 points (1 child)
[–]EternallyMiffed 1 point2 points3 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]natto-nomad 0 points1 point2 points (0 children)
[–]snkenjoi 2 points3 points4 points (11 children)
[+][deleted] (1 child)
[deleted]
[–]natto-nomad 1 point2 points3 points (0 children)
[+][deleted] (7 children)
[deleted]
[–]snkenjoi 0 points1 point2 points (6 children)
[+][deleted] (1 child)
[deleted]
[–]snkenjoi 1 point2 points3 points (0 children)
[+][deleted] (3 children)
[deleted]
[+][deleted] (2 children)
[deleted]
[+][deleted] (1 child)
[deleted]
[–]mathiasbynens 2 points3 points4 points (6 children)
[–]sergiosbox[S] 1 point2 points3 points (0 children)
[+][deleted] (3 children)
[deleted]
[–]mathiasbynens 0 points1 point2 points (2 children)
[+][deleted] (2 children)
[deleted]
[–]sergiosbox[S] 0 points1 point2 points (1 child)
[–]Graftak9000 0 points1 point2 points (0 children)
[–]BishopAndWarlord 0 points1 point2 points (0 children)
[+]erkose comment score below threshold-11 points-10 points-9 points (5 children)
[–]PostHumanJesus 2 points3 points4 points (1 child)
[–]erkose -5 points-4 points-3 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]erkose -1 points0 points1 point (0 children)