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
function(){}()
throws a SyntaxError: Unexpected token (
function(){}()
) - works fine
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?
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");
}();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With