2

I know Javascript executes code in sequential order. However I am always trying to identify whether any of the code run instantly, "line after line", after each function is compiled executed, or do all the immediate functions calls in that script wait for the entire script to finish parsing before anything is actually run.

I'd like a better understanding of the way javascript parses and execute code. Mainly for external scripts, which seem a bit hard to observe in a console log.

One applicable use, is to try and intercept the 'interactive' document.readyState as early as possible within an external script, due the fact that "interactive" state can fire extremely early at times. As per http://bugs.jquery.com/ticket/12282#comment:15

hexalys
  • 5,177
  • 3
  • 31
  • 56
  • 4
    Javascript is interpreted, not compiled – scrblnrd3 Apr 05 '13 at 01:28
  • 1
    The story is much more complicated than that on modern JS runtimes! – Francis Avila Apr 05 '13 at 01:30
  • 2
    The entire ` – Pointy Apr 05 '13 at 01:30
  • 1
    @scrblnrd3 while I understand the sentiment, that statement is not entirely correct: http://programmers.stackexchange.com/a/138541/74437 – Jason Sperske Apr 05 '13 at 01:31
  • 1
    Declarations can appear anywhere and must be processed before any code is executed, therefore a simple approach is to parse the entire script before execution begins. However, it is likely that some code can be executed before parsing has finished, but as soon as an identifier that isn't defined in the local scope (or at least that part of it that has been parsed so far) is encountered, execution must stop in case it is defined or instantiated later in the script. These sorts of implementation details are likely to vary between hosts. – RobG Apr 05 '13 at 01:35
  • @scrblnrd3: Javascript is compiled into bytecode. It's the javascript bytecode that gets interpreted. This is also true for other scripting languages like Perl or Ruby or PHP. – slebetman Apr 05 '13 at 01:36
  • And thanks for the clarification on 'interpreted' vs 'compiled' which was more of a word misuse on my part. It's worth the distinction, aside from the point of my question. I'll correct that for proper semantics. – hexalys Apr 05 '13 at 02:00
  • @RobG the problem is with function and variable hoisting. A block of code can't be executed until the parser has finished with the source to the extent that it can find all the `var` and `function` declaration statements. If the last line of a ` – Pointy Apr 05 '13 at 03:12
  • @Pointy—yes, hence why I said if early processing starts, then as soon as an unknown identifier is encountered, processing must stop until either the identifier is declared or otherwise intialised or the end of the script is encountered. It seems like an unlikely optimisation, but it would be possible. – RobG Apr 05 '13 at 06:18
  • @RobG yes fair enough :-) – Pointy Apr 05 '13 at 13:32

2 Answers2

4

No. The entire content of a script tag (regardless of whether it is inline or external) must be parsed before it can be evaluated.

This is because of the way javascript 'hoists' variable and function declarations to the top of their scope: http://elegantcode.com/2011/03/24/basic-javascript-part-12-function-hoisting/

thefrontender
  • 1,844
  • 14
  • 22
  • This can lead to some really odd performance hacks: the Gmail team loads javascript inside html comments (because HTML parsing is incremental) and then evals them when needed http://googlecode.blogspot.com.au/2009/09/gmail-for-mobile-html5-series-reducing.html – thefrontender Apr 05 '13 at 01:46
  • Ok I assumed the block has to do with the evaluation process but just needed a confirmation. I suppose the only reliable way not to miss the 'interactive' state is to have it all in the header then. Thanks – hexalys Apr 05 '13 at 01:52
  • Looks like `document.readyState` changes from 'loading to 'interactive' incorrectly in IE9 (and IE10?) sometimes. Both jQuery and domReady have adjusted their tests to account for this. In addition to the jQuery bug you linked to above, have a look at https://github.com/requirejs/domReady/issues/1 – thefrontender Apr 05 '13 at 04:21
  • Yes I believe it's a IE9 and maybe 10 issue. – hexalys Apr 05 '13 at 04:37
  • Although I don't use any library method. I prefer to call document.onreadystatechange directly. Due to this bug, I have to fallback to the 'complete' state for my otherwise 'interactive' event. The issue with 'complete' is that the window is likely to shows something you'd like to hide prior to window.load. I guess the days of having to go around crappy IE bugs is not over. :( – hexalys Apr 05 '13 at 04:46
0

Javascript is *compiled and executed one script (tag) at a time. So within each script tag, be it inline or sourced from a file, the entire code is compiled and then executed. But each individual script tag is compiled and executed in sequence.

You can check this by simply running the following two examples:

Example 1:

<html>
<script>
    alert(x);
    var x;
</script>
</html>

The code above will alert "undefined". On the other hand..

Example 2:

<html>
<script>
    alert(x);
</script>
<script>
    var x;
</script>
</html>

The code above will trigger an error because x doesn't exist.


note: * JavaScript function declaration and evaluation order

Community
  • 1
  • 1
slebetman
  • 109,858
  • 19
  • 140
  • 171