Lia.Skalkos

Life in code.

How Javascript Is Interpreted

When you work with Javascript you learn that, unlike Ruby, a function in JS can “see” and alter variables declared outside its scope. This is because of how scoping works in Javascript. An inner function could overwrite a variable declared in the outside scope, or you could redclare a local variable to give it new meaning. Seems pretty straightforward. Then I read this piece of code:

Looking at this I thought, oh, well, the variable foo is defined in the main scope, so the if block inside the function bar() will never execute when bar() is called, since bar is able to read a from the main scope. Therefore the program writes 1 to the console.

Except no, it does not. It definitely writes 10 to the console. What the &%$#^?

Here is another JS mind twister.

Now 10 should definitely log to the console, right? Nope, it’s 1. So what is going on?

This is where it turns out to be important to have some idea of how Javascript’s interpreter works, and how scoping, variable definition, and function declaration/expression all come into play. It’s kind of nonintuitive and more intertwined than I realized.

The question comes down to this: how do names actually come into scope in Javascript? It turns out it’s through a well-defined order:

  1. Language-defined

    First, JS will apply language defined names to the scope. For example, all scopes within Javascript have the keywords this. Note that only functions create scope within Javascript. Thus, if you call a function within different functional contexts, the meaning of 'this' will change.

  2. Formal parameters

    Functions can have parameters formally defined on them. JS will read these next.

  3. Function declarations

    A function declaration looks like this:

    Declared(); //This will work as long as the function definition is declared in scope
    function Declared(){ //Some stuff here; }

    Declaration are "hoisted" to the top of the scope, so that you can effective call the function from anywhere within a function.

  4. Variable declarations*

    Note that these are the last thing to be defined by the interpreter, and the assignment is then *hoisted. However, the assignment still happens at the line of code where you declared it. This variable declaration rule also applies to function expressions (as opposed to function declarations, as in above).
    a(); //This will result in an error because the variable hasn't been assigned yet
    var a = function() { //Some stuff here. };

An overview of the order in which Javascript interprets code.

With our new found knowledge we can then explain how our gnarly original Javascript brain teasers are working:

Sources:

http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html