1

Possible Duplicate:
Why can I use a function before it's defined in Javascript?

As would be expected, the following code throws an error because Foo is not defined:

window.Foo = Foo;

Also as expected, this throws the same error:

window.Foo = Foo;
Foo = function() {
    ...
};

Curiously, this works just fine:

window.Foo = Foo;
function Foo(){
    ...
};

How is this possible? Isn't JavaScript interpreted line-by-line?

1

2 Answers 2

4

Hoisting is only part of the story here.

First, to explain hoisting:

When you use var in a JavaScript program, you declare a variable. Wherever that variable is declared in a JS scope, it is hoisted to the top of that scope. JavaScript has only Global or Function scope; in the case of a function

function hoistAway() {
  console.log(a);
  var a = 5;
}

is equivalent to

function hoistAway() {
  var a;
  console.log(a);
  a = 5;
}

As you can see, the declaration is hoisted, but the initialization is not. Thus, this code would log undefined on the console, rather than 5. However, it would be satisfied that a exists.

When you don't use var, the declaration is not explicit, so it doesn't get hoisted. Thus:

function hoistAway() {
  console.log(a);
  a = 5;
}

will result in an error message.

In your examples:

window.Foo = Foo;

Foo was never declared, so you get an error.

window.Foo = Foo;
Foo = function() {
    ...
};

Again, Foo was not declared, so no hoisting. For the record:

window.Foo = Foo;
var Foo = function() {
    ...
};

will not throw an error. However, only the declaration is hoisted, so if you did something like

var bob = {};
bob.Foo = Foo;
var Foo = function() {
    ...
};

then bob.Foo would be undefined. The special case of window.Foo = Foo is weird because Foo and window.Foo are the same in the Global scope.

Finally:

window.Foo = Foo;
function Foo(){
    ...
};

works, because function declarations (as opposed to function expressions) are also hoisted; both the name and the definition gets hoisted, so this would work as intended.

Sign up to request clarification or add additional context in comments.

Comments

0

The script is parsed first, allowing your code to call functions that are defined later on.

3 Comments

Ah! I also found this right after asking: kangax.github.com/nfe "Even if declaration is positioned last in a source, it will be evaluated foremost any other expressions contained in a scope."
Yes the script is parsed first. That doesn't explain why the two types of functions behave differently. The difference is in the evaluation of function declarations vs expressions.
The conclusion is is true. However, it fails to mention why this is possible and how function statements are treated .. (function expressions are different)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.