2

I just discovered that the following code executes without error (Chrome):

console.log(fa);
function fa(){}

I was under the impression that:

function fa(){}

was identical to:

var fa = function(){};

My assumption had led me to believe that my code block above should have resulted in an error due to fa not having been declared before it was called. The second form however, when used in my code sample above, will produce an error because fa has not been defined yet when the first line runs.

Is there some documentation or information somewhere that covers the fact that the function keyword, when used declaratively, is preparsed, thus exposing said function in advance of the actual order of operation of the lines of code in a script?

Nathan Ridley
  • 33,766
  • 35
  • 123
  • 197
  • 1
    possible duplicate of [Javascript: var functionName = function() {} vs function functionName() {}](http://stackoverflow.com/questions/336859/javascript-var-functionname-function-vs-function-functionname) – hugomg Nov 09 '11 at 12:21

1 Answers1

4

The following

function fa(){}

is a function declaration which declares function fa, while

var fa = function(){};

declares a variable fa and initializes it with the result of a function expression. In JavaScript identifiers declared in a scope are hoisted to the top of the scope and hence are available throughout the scope. Initializers however are still executed in the place in the code where they appear.

Now, your function expression is executed (as any other initializer would be) at the point where it is placed in the code. Until the initializer is executed the variable holds undefined as its value.

Function declaration, on the other hand, is hoisted to the top of the scope as a whole together with the identifier under which the function is declared. Hence fa produced by the function declaration stores the right function object even when inspected above the place where the function declaration occurs.

fa1(); // valid
fa2(); // error, fa2 is undefined, not a function

function fa1() {}
var fa2 = function() {};

fa1(); // valid
fa2(); // valid

See this for more on scoping and hoisting in JavaScript.

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • `function fa(){}` is a *function declaration* and is not a statement. The right hand side of `var fa = function(){};` is a *function expression*, not a "function definition expression". See the spec: http://ecma262-5.com/ELS5_HTML.htm#Section_13 – Tim Down Nov 09 '11 at 14:34
  • I have used the terminology from "JavaScript the Definitive Guide", but after looking through the formal grammar I agree the term "function declaration statement" is misleading since it isn't a statement (see "SourceElement" in the grammar). I have updated terminology in my post to be in agreement with the specification (rather than a book). Note that this doesn't change the sense of my post. Thanks for spotting this! – Adam Zalcman Nov 09 '11 at 15:12