ECMAScript's FunctionDeclaration versus FunctionExpression
Wednesday, 7. February 2007, 13:44:18
function Identifier ( FormalParameterListopt ){ FunctionBody }
while a FunctionExpression is the anonymous function - note in the definition that the "Identifier" part is marked as optional:
function Identifieropt ( FormalParameterListopt ){ FunctionBody }
However, including an identifier is still allowed. The identifier can be used inside the function to refer to itself, but not outside it.
This may confuse authors if we forget that whether something is a FunctionDeclaration or a FunctionExpression depends on the context. The right hand side of an assignment or the arguments of a function call will be a FunctionExpression, in other words behave like an anonymous function. For example
var a=function b(){return 'Hi'}; alert(b());
fails: there is no function named b there. alert(a()) would work. Likewise,
setTimeout( function a(){}, 50 ); a();
fails because the argument is evaluated as a FunctionExpression and after the setTimeout() call no function named "a" exists. (IE seems to violate/extend the standard here!)
It can be confusing that a FunctionExpression is allowed to look exactly like a FunctionDeclaration but behaves differently, and I don't really see a strong use case since arguments.callee exists.









Hallvord R. M. Steen # 7. February 2007, 16:24
_Grey_ # 8. February 2007, 01:18
if((function b(){}) instanceof Function){alert(window.b)}// didn't expect this to be 'undefined' in non-IE
Also didn't know IE would accept stuff like your examples. Good to know (could help prevent cluttering global object in IE). Any workarounds for IE, though? Is there no way to use it as in other browsers?
David Andersson # 10. February 2007, 12:36
Inspired by bug 227785 I've been writing on an article about how function declarations and function expressions work, so I've got some code examples to show differences in behaviour. This snippet tests whether a named function is bound in the contained or the surrounding scope, to illustrate this behaviour of JScript:
Also a lot of code for other differences. This for example:
bogus:{Is an example where JavaScriptCore compile time initialises fn but SpiderMonkey delays initialisation till control flow has reached it (which it of course won't).break bogus;
function fn(){return'bogus!'}
}
alert(typeof fn==='function'&&fn());
On the other hand, for an if statement:Here JavaScriptCore and SpiderMonkey both delay initialisation, while JScript and linear_b compile time initialise.
Hallvord R. M. Steen # 26. February 2007, 03:24
Otherwise I hope you will allow me to use some of your examples if I get around to writing that article before you do?
David Andersson # 3. March 2007, 12:20
And of course you can use my examples if you write the article before I do.