7

I've always thought that browsers execute JavaScript code from top to bottom string by string(you kinda expect this behavior from a scripting language). But clearly it's not the case here:

//works perfect

<script>
  test();
  function test() { alert('test'); }
</script>

but if I declare function as a variable it fails with 'Uncaught ReferenceError: test is not defined':

<script>
  test();
  var test = function() { alert('test'); }
</script>

So the javascript engine sometimes doesn't execute the code from top to bottom. It can somehow preload functions even if they're declared in the end. How exactly does it work and why?

Kirill Ivlev
  • 12,310
  • 5
  • 27
  • 31
  • I believe function(){} is just a special case, which gets moved to the top of the scope. I could be wrong though. – crimson_penguin May 24 '13 at 22:56
  • 4
    It is parsed fully before it is executed into something *like* a [AST](http://en.wikipedia.org/wiki/Abstract_syntax_tree). This is why you can see "Syntax Errors" for lines further down the source. – Matt May 24 '13 at 22:56
  • Take a look at the top answer here : http://stackoverflow.com/questions/336859/javascript-var-functionname-function-vs-function-functionname – viper May 24 '13 at 22:58
  • [A good answer](http://stackoverflow.com/questions/7609276/javascript-function-order-why-does-it-matter/7610883#7610883) on the subject of hoisting – Some Guy May 24 '13 at 23:01

1 Answers1

9

This is an example of function and variable hoisting: function and variable declarations get moved to the top of the current scope.

Your examples are internally converted to this:

Case 1:

<script>
  function test() { alert('test'); }
  test();
</script>

Case 2:

<script>
  var test;
  test();
  test = function() { alert('test'); }
</script>

From this you can infer, that in the second case the variable test is undefined, when you try to execute it.

Sirko
  • 72,589
  • 19
  • 149
  • 183