What is the difference between those self-executing anonymous function (aka IIFE) implementation

In many books / blog posts the self invoking anonymous function pattern is written like this:

(function() {
  var foo = 'bar';
})();

However running a JSLint on this gives this error:

Move the invocation into the parens that contain the function.

e.g. changing it to this works:

(function() {
  var foo = 'bar';
}());

Questions

  1. Why is the first implementation not good enough for JSLint? What are the differences?
  2. What is the preferred form? is JSLint always right?
  3. Why does it work? after all function(){}() throws a SyntaxError: Unexpected token (
    But wrapping it with parens makes it all of a sudden work? e.g. (function(){}()) - works fine
    (After all this is JavaScript, not Lisp, so what is the effect of the wrapping parens on the ohterwise syntax error?)

EDIT: this is somewhat of a followup to this (I would not say exact duplicate though): JSLint error: "Move the invocation into the parens that contain the function", so my main question is #3, why does it work at all?

Answers:

Answer

I don't know how Crockford's opinions were developed, but I can explain why wrapping in parens works.

The function function() { ... } syntax in JavaScript can represent two different things: a function declaration or a function expression.

A function declaration is a statement that defines the function within the current scope under the specified name.

function example() { 
    alert("Hello World");
}

example();

A function expression is an expression that evaluates to a new Function instance.

var secondExample = function example() {
    alert("Hello World");
};

secondExample();
example(); // <-- throws an Error: example is not defined.

Whether a occurrence of the syntax is a function declaration or function statement depends on what the parser was expecting. JavaScript's parser is simple. It won't look ahead and notice that the function is followed by (), therefore it should treat it as a expression. It just sees the function at the beginning of a line, and therefore treats it as a statement, which causes a syntax error when it's followed by (). When you wrap it in parentheses, the parser is instead expecting an expression, and it works.

Wrapping in parentheses (wherever you place them) is the the clearest way to do this, but anything that causes the parser to expect an expression will work. For example, the bitwise NOT operator ~:

~function() {
    alert("Hello World");
}();
Answer

1.

Apparently this is an issue with conventions. Having the first example shows a "lack of convention" (source). As far as actual differences, there are none. Both will execute without error.

2.

In this case, I prefer your first example, but that is just my convention. JSLint is often right. So if you want to follow their naming conventions then when it shows a warning based on convention it would make sense to conform to the convention.

3.

This works because wrapping the function(){} inside of a () makes it an expression, which once paired with the final () immediately invokes it. Hence you have an Immediately Invoked Function Expression.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.