Can I immediately call(invoke) a named function expression without a variable name like this?
var bookingMask = function (ac) {
....
}('.selectDates');
If you really mean "named" function expression, yes, you can do that:
(function bookingMask(ac) {
// ...
})('.selectDates');
Note the () wrapping it. Otherwise, the function keyword would lead the parser to assume that it was the beginning of a function declaration, which you can't directly invoke in that way.
You might want that if you want to use bookingMask inside the function (e.g., recursion).
Live Example:
(function bookingMask(ac) {
console.log("ac is: " + ac); // "ac is: .selectDates"
console.log(typeof bookingMask); // "function"
})('.selectDates');
If you meant bookingMask to be the result of the call, you can do that too:
var bookingMask = (function nameForTheFunctionHere(ac) {
// ...
})('.selectDates');
If you're doing that, since the parser is already expecting an expression as of the function keyword there, you don't need the wrapper (), this is fine:
var bookingMask = function nameForTheFunctionHere(ac) {
// ...
}('.selectDates');
...but I tend to keep them anyway, since it's really easy when reading the code to miss the (...) at the end.
You can also do it without a name (just remove bookingMask above), but you did specifically say "named", so... :-)
(If anyone's wondering why this answer has four downvotes, when I first posted an answer I missed the fact that the OP had mentioned a named function expression, not least because there isn't one in the question. A couple of people were kind enough to let me know so I could fix it. But people were initially voting on the incorrect answer.)
There are 2 different ways of declaring a function, you can either use function declaration or function expression. The 'expression' part means that it is either assigned to a value var func = function cat(){} or you use parentheses to tell the JavaScript engine to go get the value inside and evaluate it as an expression. So the name IFFE, immediately invoked function expression comes from first turning the function into an expression (function(){}) then calling it (function(){})().
So in your case, you do not want to evaluate the function 'assigning it to a variable' you want to create assign and run the function at once like so...
(function(ac) {
// code...
})('.selectDates');
If your feeling very adventurous you can also use other operators other than the parentheses to evaluate the IFFE such as;
+function IFFE(){
}()
-function IFFE(){
}()
Related
I would like to store a function definition in a string, like for example:
var funcString = 'function(){ return 4+4 }'
Can I use eval() to evaluate the function?
Like for example:
var result = eval(funcString)
which will evaluate the string in funcString as a function and return 4+4 (8) in result.
edit: So from what you've told me I understood that I shouldn't use eval in that way, but for my case I don't think there is another way.
I would like to define a set of rules in a separate file and I want to instruct my Javascript Library to look into this file and search for the rules. The following is an example of a rule:
rule('logOut', (function() { return !JSLibrary.compareUserDetails })(), (function() { console.log("\n\nError: logged out user did not match\n\n\n") })())
I would like to evaluate both of the functions defined in the rules and I think that eval is the only way to do it. I don't know if there exist any other.
Fair warning, eval is "evil." I'll answer your question regardless, but you might want to rethink using eval.
In JavaScript, functions are values, just like 5, 'Stack Overflow' and document. In fact, what function myFunction(args) { body } does is create a function and throw it into a variable called myFunction*.
Say you wanted to take that function and put it into another variable. You can just say var otherVariable = myFunction. And if you want to call that function, you can just say otherVariable().
But say you want a function that isn't bound to a name, for instance if you're passing it to another function. You can use an anonymous function, defined as function(args) { body }. That's what's inside the string you're eval-ing. Anonymous functions are just like any other function, and you can call them as such. Actually, you can even call them right out of the result of eval by tacking on some parentheses at the end.
Unfortunately, it's not that easy though. You can't just write a line of code with an anonymous function definition and expect it to run: you will instead get an error complaining about it not being named. To fix this, throw some parenthesis around the definition to force it to be an expression instead of a statement.
Your final working code will look like this:
var funcString = '(function(){ return 4+4 })'
var result = eval(funcString)()
Sure, you should never use eval for this particular use, but I hope you learned a bit about JavaScript from this answer anyways.
* There's more to it than that, such as hoisting, but that doesn't really matter in this explanation.
Use of an immediately invoked function expression can call a function with eval.
document.body.innerHTML = eval('(function(){return 4+4;})()');
WARNING: do not ever do this: it's insecure, a performance-killer, harder to read/understand, etc
This question already has answers here:
Explain the encapsulated anonymous function syntax
(10 answers)
Closed 7 years ago.
I'm reading up on JavaScript IIFE and so far the understand concept, but I am wondering about the outside parenthesis. Specifically, why are they required? For example,
(function() {var msg='I love JavaScript'; console.log(msg);}());
works great, but
function() {var msg='I love JavaScript'; console.log(msg);}();
generates a syntax error. Why? There are lots of discussions on IIFE, but I'm not seeing a clear explanation about why the parentheses are required.
There are two ways to create functions in JavaScript (well, 3, but let's ignore new Function()). You can either write a function declaration or write a function expression.
A function declaration in itself is a statement and statements by themselves don't return values (let's also ignore how the debugging console or Node.js REPL print return values of statements). A function expression however is a proper expression and expressions in JavaScript returns values that can be immediately used.
Now, you may have seen people saying that the following is a function expression:
var x = function () {};
It may be tempting to conclude that the syntax:
function () {};
is what makes it an expression. But that's wrong. The syntax above is what makes it an anonymous function. And anonymous functions can either be a declaration or an expression. What makes it an expression is this syntax:
var x = ...
That is, everything to the right of an = sign is an expression. Expressions make it easier to write math formulas in programming languages. So in general everywhere that math is expected to be processed is an expression.
Some of the forms of expressions in JavaScript include:
everything to the right of an = operator
things in braces () that are not function call braces
everything to the right of a math operator (+,-,*,/)
all the arguments to the ternary operator .. ? .. : ..
When you write:
function () {}
it is a declaration and does not return a value (the declared function). Therefore trying to call the non-result is an error.
But when you write:
(function () {})
it is an expression and returns a value (the declared function) which may be used immediately (for example, may be called or may be assigned).
Note the rules for what counts as expressions above. From that it follows that braces are not the only things that you can use to construct an IIFE. Below are valid ways for constructing IIFEs (because we write function expressions):
tmp=function(){}()
+function(){}()
-function(){}()
0/function(){}()
0*function(){}()
0?0:function(){}()
(function(){}())
(function(){})()
You may actually see one of the above non-standard forms (particularly the + version) in third-party libraries, because they want to save one byte. But I strongly advise you to only use the brace forms (either are fine), because they are widely recognized as IIFEs by other programmers.
The version of IIFE that is wrapped in parenthesis works, because this marks the declaration of the internal function declaration as an expression.
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
For more detailed explanation please see:
Advanced JavaScript: Why is this function wrapped in parentheses?
HINT:
The invocation operator (()) only works with expressions, not declarations.
This will be a long-winded answer, but will give you the necessary background. In JavaScript there are two ways functions can be defined:
A function definition (the classical kind)
function foo() {
//why do we always use
}
and then the more obscure type, a function expression
var bar = function() {
//foo and bar
};
In essence the same thing is going on at execution. A function object is created, memory is allocated, and an identifier is bound to the function. The difference is in the syntax. The former is itself a statement which declares a new function, the latter is an expression.
The function expression gives us the ability to insert a function any place where a normal expression would be expected. This lends its way to anonymous functions and callbacks. Take for instance
setTimeout(500, function() {
//for examples
});
Here, the anonymous function will execute whenever setTimeout says so. If we want to execute a function expression immediately, however, we need to ensure the syntax is recognizable as an expression, otherwise we have ambiguity as to whether of not we mean a function expression or statement.
var fourteen = function sumOfSquares() {
var value = 0;
for (var i = 0; i < 4; i++)
value += i * i;
return value;
}();
Here sumOfSquares is immediately invoked because it can be recognized as an expression. fourteen becomes 14 and sumOfSquares is garbage-collected. In your example, the grouping operator () coerces its content into an expression, therefore the function is an expression and can be called immediately as such.
One important thing to note about the difference between my first foo and bar example though is hoisting. If you don't know what that it is, a quick Google search or two should tell you, but the quick and dirty definition is that hoisting is JavaScript's behavior to bring declarations (variables and functions) to the top of a scope. These declarations usually only hoist the identifier but not its initialized value, so the entire scope will be able to see the variable/function before it is assigned a value.
With function definitions this is not the case, here the entire declaration is hoisted and will be visible throughout the containing scope.
console.log("lose your " + function() {
fiz(); //will execute fiz
buzz(); //throws TypeError
function fiz() {
console.log("lose your scoping,");
}
var buzz = function() {
console.log("and win forever");
};
return "sanity";
}()); //prints "lose your scoping, lose your sanity"
There is a JSLint option, one of The Good Parts in fact, that "[requires] parens around immediate invocations," meaning that the construction
(function () {
// ...
})();
would instead need to be written as
(function () {
// ...
}());
My question is this -- can anyone explain why this second form might be considered better? Is it more resilient? Less error-prone? What advantage does it have over the first form?
Since asking this question, I have come to understand the importance of having a clear visual distinction between function values and the values of functions. Consider the case where the result of immediate invocation is the right-hand side of an assignment expression:
var someVar = (function () {
// ...
}());
Though the outermost parentheses are syntactically unnecessary, the opening parenthesis gives an up-front indication that the value being assigned is not the function itself but rather the result of the function being invoked.
This is similar to Crockford's advice regarding capitalization of constructor functions -- it is meant to serve as a visual cue to anyone looking at the source code.
From Douglass Crockford's style convention guide: (search for "invoked immediately")
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.
So, basically, he feels it makes more clear the distinction between function values, and the values of functions. So, it's an stylistic matter, not really a substantive difference in the code itself.
updated reference, old PPT no longer exists
Immediately Called Anonymous Functions get wrapped it in parens because:
They are function expressions and leaving parens out would cause it to be interpreted as a function declaration which is a syntax error.
Function expressions cannot start with the word function.
When assigning the function expression to a variable, the function itself is not returned, the return value of the function is returned, hence the parens evaluate what's inside them and produce a value. when the function is executed, and the trailing parens ..}() cause the function to execute immediately.
Or, use:
void function () {
...
} ()
I was wondering, what is the significance of the additional parenthesis when initializing an object. For example:
var foo = function(){ ... }();
versus
var foo = (function(){ ... }());
I assume something related to scope but I was wondering if someone can be more precise about the specific differences since they both seem to initialize an object based on what each anonymous function returns.
In that specific case, there's no effective difference.
Some people like the outer (...) because it gives them a visual hint near the = operator that the function is being invoked.
But the assignment operator causes the function to be evaluated as the expression that is the right hand operand of the assignment operator, and as such it can be invoked without any further need to coerce it out of a function declaration.
Without the assignment, there needs to be some syntax involved that lets the interpreter know that the function keyword is being used as an anonymous function expression.
For example...
(function() {
// code
})();
Here the parentheses resolved the ambiguity of function so that it's treated as the single expression inside the (...) group.
The grouping operator is just one way of forcing a function to be evaluated as an expression. Most JavaScript operators can be used for this purpose. Unary operators are probably safest, for example...
!function() {
// code
}();
...or...
void function() {
// code
}();
In both cases, the function is seen as the single operand to the respective operator.
Both are functionally equivalent.
However, as a convention, many programmers prefer the opening parenthesis to denote the var is the result of a function, and not the function itself.
The use of self-calling functions is to pass in variables to preserve their "namespaces", for example, it's common to pass in window or document, or other things like jquery.
According to some quick tests on jslint, the preferred way of doing so is the first (foo) in the following tests.
var foo = (function () {}());
var bar = (function () {})();
var baz = function () {}();
Note the that invoking () are inside of the outer parenthesis.
JSLint gives the following errors for bar and baz
Error:
Problem at line 2 character 28: Move the invocation into the parens
that contain the function.
var bar = (function (w) {})(window);
Problem at line 3 character 27: 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.
var baz = function (w) {}(window);
As far as I know, this is just a convention and isn't absolutely necessary.
This is a good post about why this convention is useful:
http://peter.michaux.ca/articles/an-important-pair-of-parens
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.