This is going to be a quick discussion, but I just wanted some feedback on a revelation I had this morning. Knowing that this...
var addTwoNumbers = function(intOne, intTwo) {
if ((typeof intOne == 'number') && (typeof intTwo == 'number')) {
document.write(intOne + intTwo);
} else {
document.write('Unable to perform operation.');
}
};
addTwoNumbers(3, 4);
... behaves essentially the same as this...
(function(intOne, intTwo) {
if ((typeof intOne == 'number') && (typeof intTwo == 'number')) {
document.write(intOne + intTwo);
} else {
document.write('Unable to perform operation.');
}
})(3, 4);
... is that to say that the first set of parentheses in the self-invoking function is a "tool" to bypass or work around function execution by reference? In effect, ()
is the name of the method without actually being the name of the method? Also, because the function is being declared directly at execution, is it faster than the technique using a variable name reference? Just wondrin'.
functionName()
vs. ()()
- The difference in how the expressions are handled. The bit before the parameter handling parentheses - 65Fbef05 2012-04-05 16:46
!functionName() {}
? I guess I don't follow, could you elaborate with an example - 65Fbef05 2012-04-05 16:51
OK here's the reason that "self-invoking functions" (which really aren't "self-invoking"; there's an explicit invocation and it's outside the function proper) are written (by convention) as a parenthesized subexpression.
JavaScript has two constructs involving the keyword function
:
The function declaration statement, which defines a function object and binds it to a name in the local scope (as well as in the function's local scope but let's ignore that for now):
function foo() { /* code */ }
The function instantiation sub-expression, which creates a function object in the context of an expression:
var f = function() { /* code */ };
The problem comes about when you want the second thing, and you want it at the beginning of an expression statement. When the statement starts with the keyword function
, the parser assumes that you're doing 1 above, not 2. Thus, by introducing parentheses around the function instantiation — and remember that parenthesizing a sub-expression is always allowed and does not affect its value in any way — makes the use of the function
keyword be interpreted as 2 above.
There are other ways of forcing the parser to see the statement as an expression too:
!function() { /* code */ }();
0, function() { /* code */ }();
+function() { /* code */ }();
are just some examples.
As to performance, it's a non-issue here. One thing I will note is that this way of binding an identifier to a function object:
var name = function() { /* code */ };
is really no better than:
function name() { /* code */ }
and in some ways it's worse. In particular, using a function declaration statement gives a name that will show up in stack traces, while defining the function with var
does not.
function
is taken to be a function declaration statement. The parentheses are a way to have the parser recognize the statement as being an expression statement, so that thefunction
keyword will be interpreted in that light instead - Pointy 2012-04-05 16:40