I'm having some trouble understanding how both of these two lines are inter-changeable.
( function() { return console.log("anon inner 1"); } ) ();
// ^^ invoke
( function() { return console.log("anon inner 2"); } () );
// ^^ invoke
In the first line, we have an anonymous inner function that is wrapped in parenthesis, and then immediately invoked. The second line, we have an anonymous inner function that is invoked and then wrapped in parentheses.
I guess my question is, what does the wrapping in parenthesis do? Does it objectify stuff, that is, turn things into object?
JavaScript has a function statement, which is the "standard" way to declare a function, with the syntax:
function name([param1, 2...]) {
statements
}
And there is a function operator, which looks the same as the function statement except that the name is optional and it is used not as a statement on its own but where an expression is expected as in the following two examples:
// declare variable name that references a function created by expression
var name = function([param1, 2...]) { statements };
// call someOtherFunction that expects a function as a parameter
someOtherFunction(function() { });
(There are plenty of other ways to use function expressions.)
If you try to have an anonymous function on a line by itself without wrapping it in parentheses it will taken to be a function statement and thus be a syntax error because there's no name. Wrapping it in parentheses means it'll be treated as an expression inside the parens and not as a statement so then name is optional. If you assign the result of the function expression to a variable or use it in some other way (like in my examples above) then you don't need the parentheses.
So getting (at last) to the syntax mentioned in the question: once you have the parens and your function is treated as an expression you can use either of the two syntaxes you posted to invoke it. The first, invoke "outside" the parens means the first set of parens will evaluate as having the value of the expression inside, which happens to be a function that you can then invoke. The second, invoke "inside" means function expression will be invoked and then the surrounding parens will evaluate to whatever the function returns.
Either way, the return value of the function is thrown away because you don't assign it to anything.
(Final note: a function expression can have a name so that the function can call itself recursively.)
When you have a regular annon function like:
function() { alert('testing'); }
it's a function expression. Any other vairiation is called a function declaration, like the following:
function a() { alert('testing'); }
!function() { alert('testing'); }
var a = function { alert('testing'); }
(function() { alert('testing'); })
Now a function expression can't be invoked as it's not returning a value, but a declaration can. So all you need to do is somehow switch it to a declaration to immediately invoke, which is what the parens do, whether they wrap the invoking parens or not. This is because once the js parser sees a open parens it makes it into a declaration.
Disclaimer: I may have mixed up the terminology of declaration and expression
Related
What is the reason of putting ( ) in the end for Immediately Invoked Function Expression in javascript
(function() {
// Code that runs in your function
})( /* this parenthesis in the end */ )
An Immediately Invoked Function Expression is a:
(function() { ... }) ← Function Expression which is Immediately Invoked → ()
To elaborate, (function() { ... }) is merely defining the function, and a function which is defined but never called is doing absolutely nothing.
In order for the code in the function to be executed, it needs to be invoked (often referred to as calling the function). That is why you wrap the function definition in parentheses (making it an expression that evaluates to a reference to the function) and then immediately invoke (or call) the function with any arguments () - or no arguments as in your sample.
It is more or less equivalent to doing this:
const someFunc = (function() { ... }); //merely assigns a function, the code inside doesn't run
someFunc(); //invokes the function (but in this case it isn't immediate)
except in this case you've bound the function reference to a variable and so it is no longer an IIFE.
The reason is purely syntactical. The JavaScript parser has to be able
to easily differentiate between function declarations and function
expressions. If we leave out the parentheses around the function
expression, and put our immediate call as a separate statement
function(){}(3), the JavaScript parser will start processing it, and will conclude, because it’s a separate statement starting with the
key- word function, that it’s dealing with a function declaration.
Because every function declaration has to have a name (and here we
didn’t specify one), an error will be thrown. To avoid this, we place
the function expression within parentheses, signaling to the
JavaScript parser that it’s dealing with an expression, and not a
statement. There’s also an alternative way of achieving the same goal:
(function(){}(3))
By wrapping the immediate function definition and call within
parentheses, you can also notify the JavaScript parser that it’s
dealing with an expression.
Those four expressions are variations of the same theme of
immediately invoked function expressions often found in various
JavaScript libraries:
+function(){}();
-function(){}();
!function(){}();
~function(){}();
This time, instead of using parentheses around the function
expressions to differentiate them from function declarations, we can
use unary operators: + , - , ! , and ~ . We do this to signal to the
JavaScript engine that it’s dealing with expressions and not
statements.
Reference: johnresig.com/
While I was expecting that this code
var a = eval("function() { return 1; }");
console.log(a());
prints '1' in the console, I get a syntax error Uncaught SyntaxError: Unexpected token (. What am I doing wrong here?
I am working with a framework that allows to define javascript functions in the configuration, so I have no other choice but using eval.
The function keyword is ambiguous in Javascript: it can start a function declaration (a statement), or a function literal (an expression). When function is encountered in the statement position, the parser voluntarily prefers declaration over expression. Since eval expects a statement, this makes your code invalid -- function name is required for declarations. You can either provide a name:
eval('function foo() {...}')
or force the parser into the expression mode
foo = eval('( function () {...} )')
in which case function will be treated as a literal.
This is basically the same story as with {}, which can be either a block or an object literal. Something like eval('{1:2}') will fail for exactly the same reason (statement preferred over expression).
The problem is that you have a function declaration and that requires a name. For reference, this is a function declaration
function myFunc() { console.log("executed") } //<-- declaration
myFunc(); //<-- execution
What you expect to have is an unnamed function expression
var myFunc = function() { console.log("executed") }
//expression ^------------------------------------^
myFunc(); //<-- execution
Or for a truly unnamed function that you do not assign to a variable, you can have an IIFE
// v--------- brackets surrounding expression ---------v
( function() { console.log("executed") } )()
//expression ^------------------------------------^ ^^
//execution -------------------------------------------++
However, in JavaScript a standalone statement that starts with the function keyword will be treated as declaration and if it doesn't have a name, it is invalid.
However, you can go around that by surrounding the expression in brackets to make it acceptable for the parser.
//brackets v--------------------------v
var a = eval("( function() { return 1; } )");
// ^----------------------^ function expression
console.log(a());
You cannot mix function declaration and function expressions this way. You have to do the full declaration or expression inside the eval().
eval("function a() { return 1; }");
console.log(a());
This would work, as we give the function declaration a proper name, a, and then call the function this creates on the global scope.
eval("var a = function() { return 1; }");
console.log( a() );
This would also work, since the function expression assigning it to the variable a is now part of what gets evaluated. And we can then call the function in it's scope.
Neither of these should actually ever be used if there's alternatives.
The most common alternative is using new Function();.
var a = new Function( 'return 1;' );
console.log( a() );
This achieves the same end result and is slightly safer than using eval().
I would be surprised though if this was the only way the framework allows to define extra javascript functions. I guess that since it's in the config of something the security issues this gives are less important than if it's public code. But i would reread the docs of the framework to double check that this is the only option.
As the comments are 100% true that a function must contain a name or has to be initialised as an anonymous function, there is a solution to your problem.
If you want to create a function by text you could use the function constructor
new Function ([arg1[, arg2[, ...argN]],] functionBody)
For more information look at https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function
For one of them the "()" is inside, for the other one it is outside. Here they are:
var a = (function() {
return {
bla: function() {
console.log('a');
}
};
} () );
var b = (function() {
return {
bla: function() {
console.log('b');
}
};
}) ();
a.bla();
b.bla();
There is no difference.
The [unnecessary] parenthesis are just in different places. The function declaration is already an expression due to where it is located. The parenthesis would make a difference, while still resulting in equivalent code, if the declaration was in a statement context (and ironically they would turn it back into an expression context), which it is not.
The common use of parenthesis in a similar scenario is for self-invoking functions. The parenthesis are required in this case because
function x () { alert("hi!") } ()
is parsed as
function x () { alert("hi!") }; ()
when it appears as a statement -- or "top level element of a block" -- where it is parsed as a "FunctionDeclaration". Thus the following form is often used:
(function () { alert("hi!") })()
This works because function ... is no longer a statement, as above, but an expression (parsed as a "FunctionExpression"), and the expression can continue so the Automatic Semicolon Insertion does not occur as in the previous case. Also note that the function name can be omitted.
However, because in the post the function ... appears in an on the right of an = (in an "AssignmentExpression") it is therefore already in an expression context (is parsed as a "FunctionExpression") and thus no additional parenthesis are needed.
All of these are identical, but I prefer the 2nd form (for consistency within my code):
a = function () {} ()
b = (function () {}) ()
c = (function () {} ())
Happy coding.
There is no real difference. Both work in the same way. If you want to pass JSLint, you will need to use the first pattern, where the invocation parentheses are inside the other set of parentheses. If you don't, you will get the following error:
Move the invocation into the parens that contain the function.
Also note that the first set of parentheses are not required. It will work without them, but again will fail JSLint:
Wrap an immediate function invocation in parentheses to assist the
reader in understanding that the expression is the result of a
function, and not the function itself.
A couple of related questions:
JSLint error: "Move the invocation into the parens that contain the function"
Solution for JSLint errors
There is no practical difference, it's just a subtle difference in how you make the Javascript engine think of the function as a value.
Using ( function(){} () ); you are causing the function to be a value because a statement can't start with a parenthesis. Using ( function(){} ) (); you are using the parentheses to first evaluate the function as a value, then call it.
I think is the same difference of this:
var myObj = {bla:'blabla'};
var a = (myObj);
var b = myObj;
...no difference :)
the ending brackets mean that : When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself. (taken from here)
So, if you use {}(), the function is immediately executed and the variable is assigned with the function result.
Then if you use ({})(), if there's a function between (), it is executed and the value is assigned to the variable.
They are the same thing if they contain the same functions in my opinion.
bit of a silly question perhaps.
But I want to understand why the syntax on the self-executing function and the callback it has is so different to all the other JS syntax..
(function () {
})()
I just need to understand why its valid to encapsulate it with () I wouldn't have guessed that to be valid, and then the extra () afterwards for the callback, (which just sits directly after it, I also wouldn't have expected that to be valid.
Is anyone able to explain this to me?
The function (...) {...} part is a function expression, that is, an expression that represents a function. The only reason it has to be wrapped in parentheses in this case is that if the keyword function is the very first thing in a statement, then the statement is assumed to be a function statement, that is, a function declaration. (Actually, it doesn't necessarily have to be wrapped in parentheses; it also works to prefix it with a +, or in general to put any sort of token before function that prevents the function-statement interpretation.)
The () part after the function expression is the same as the normal () for calling a function. This:
(function (...) {...})(...);
is (aside from the temporary variable) the same as this:
var f = function (...) {...};
f();
which is equivalent to this:
function f(...) {...};
f();
Essentially the outer parentheses allow the function object to be fully interpreted and instantiated, so that once you exit the scope of those parentheses the function object is ready to be called.
See here:
Why do you need to invoke an anonymous function on the same line?
When declaring as you did, you are using it as a function expression (3rd way of defining the function from the above link). As with any expression, this (expression) evaluates to expression - parentheses are used here is establish precedence where necessary. So you can write this for example:
var f = function(a) {
var s = (((( 1 )))) + (((( a ))));
console.log(s);
};
((((( f ))))) (2);
(live example) and then remove all the unnecessary parentheses with the same result (which is printing of 1 + 2 = 3, essentially). The result of:
(function(...) { ... })
is a function that accepts some arguments and has a body to be executed. This:
(function(...) { ... })()
is pretty much equivalent to:
var f = (function(...) { ... });
// Now f is a function that can be called
f();
Anonymous functions are useful, among other things, for two reasons - they are anonymous (i.e. they don't create additional names - see again the above SOq link) and they are "containers" for other stuff that doesn't need to be global.
What you have here is an Immediately-invoked function expression also known as IFFE (read iffy) and is a design pattern which produces lexical scope using JS function scoping. These are used to avoid variable hoisting, polluting the global environment and simultaneously allowing public acces to methods while retaining the local privacy of variables declared whithin the function.
The key to understanding this is that JS has function scope and not block scope and passes values by reference inside a closure.
You can read further into this at Immediately-invoked function expression.
Bootstrap css uses the following:
!function( $ ) {
}( window.jQuery )
That's different than the self-invoking anonymous function call that I originally learned:
(function($) {
})(jQuery);
Q: Is that just preference you think? I mean the not symbol instead of enclosing it in parenthesis.
"Q: Is that just preference you think?"
Yes, but using a unary ! operator, you can avoid a few bugs when you forget a semicolon before the IIFE, which can cause the () to be interpreted as a function call.
alert('foo') // alerts 'foo'
(function() { // TypeError: undefined is not a function
alert('bar');
})()
Here the outer () is interpreted as a function call. It's trying to call whatever was returned from the alert() function, which of course returns undefined, which isn't a function.
alert('foo') // alerts 'foo'
!function() {
alert('bar'); // alerts 'bar'
}()
No troubles with this one, since the ! is a unary operator that only evaluates the operand to its right.
A statement starting with the function keyword is treated as a function declaration and must be followed by a name that is a valid identifier.
An anonymous function expression starts with the word function, but since there is no name, it can't be used where it might be confused with a function declaration. In most cases, the grouping operator is used to indicate a function expression:
(function() {
/...
}());
or
(function() {
/...
})();
You can also do:
var foo = function() {
}();
In all of the above, the function keyword isn't at the start of the statement so it's treated as the start of a function epxression. A name isn't required and the function can be immediately called.
It's the same with !function.... The parser sees the ! and says "what follows is an expression". When it gets to function it knows it's the start of a function expression.
Using !function… instead of (function…) saves a single character, and possibly creates a bit of confusion as it's a less common way to write a function expression.