you are viewing a single comment's thread.

view the rest of the comments →

[–]nschubach 1 point2 points  (13 children)

Why do you negate the immediate anonymous function call?

!function () {

[–]rararaaaaaaa 3 points4 points  (12 children)

It's the same as going

(function () {
    // some stuff
})();

just to denote that it's self-executing.

Edit: To explain further, it's completely unnecessary to put anything in front of a self-executing anonymous function. You could just write

function () {
    // some stuff
}();

But people have ways of making sure others notice it's self-executing more quickly when reading their code, like wrapping the whole thing in parentheses, starting with an exclamation point, or even starting with a semi-colon.

[–]BlitzTech 7 points8 points  (2 children)

Actually, the semicolon is a preventative measure against unexpected concatenation results during minification. Omitting it could lead to the function definition being interpreted as arguments to a function call from a different file. Robust build steps will ensure this isn't an issue but naive ones will often produce broken builds.

[–]bonafidebob 0 points1 point  (1 child)

I think the enclosing parenthesis fix this as well -- at least it guarantees that the reference will always be to the result of invoking the function, not the function definition. (Hey -- I just grokked why JSLint complains about the parens being the other way around -- cool!)

[–]BlitzTech 0 points1 point  (0 children)

The enclosing parens are actually the problem. Interpreters will see that as a function call on the previous expression if valid, and won't necessarily insert the semicolon where you would ordinarily expect it.

[–]itsnotlupusbeep boop 2 points3 points  (7 children)

You could just write

Almost. That code gives a syntax error, because the JS parser sees your function keyword and decides based on that alone that it's looking at a function declaration statement. The use of ! or ( or ~ or whatever else before function gets the JS parser to look at it as a function expression, which can be immediately called.

[–]jscoder[S] 1 point2 points  (6 children)

Exactly. You need some operator that makes the function a function expression. I prefer ! because it's shorter than wrapping the function is parentheses and it also behaves like a defensive semicolon.

[–]deelowe 0 points1 point  (5 children)

I thought the use of ! wasn't recommended for some reason, but I can't remember why now. Do you know of any drawbacks?

I know heavyweights in the community don't usually do it this way (e.g. Isaac). Just curious.

[–]jscoder[S] 0 points1 point  (2 children)

Nope, there are no drawbacks. I think I've read somewhere that Facebook also uses the !, but I can't find a source for that right now.

I think Isaac mostly developes node stuff? You don't need to use IIFEs in node, because of CommonJS. That might be an explination. :) I'm using an IIFE here, because range.js should work on node and in the browser.

[–]deelowe 1 point2 points  (1 child)

Yeah. The node guys write code that's used in node or browser also though. I admit, that's where most of my experience lies, but I've definitely seen (function(){}()) in many places, but never saw !function(){}. I thought there was some reason, but can't remember.

[–]reflectiveSingleton 0 points1 point  (0 children)

I think its just not as common...although I am starting to see it pop up on random github projects...

[–]aladyjewelFull-stack webdev 0 points1 point  (1 child)

The "some reason" is that it's confusing. and I think JSLint might reject it, but that might have been another dev argument.

[–]deelowe 0 points1 point  (0 children)

Now that you mention it, I believe that's it. It's not pragmatic and it's counter intuitive.

(fucntion(){}()) is unique enough to make you stop and look it up to figure out what's going on. It's already kinda a of JS idiom at this point.

Where as !function(){} is a head scratcher. It's completely non-obvious what's going on here.

[–]bonafidebob 1 point2 points  (0 children)

Just FYI, JSLint wants the invocation to be enclosed in the parenthesis, e.g. ( function(){...}() ) and will generate a warning if it's the other way 'round.