Making sense of Javascript execution contexts and the scope Chain


Last night I spent a good deal of time studying javascript execution contexts and scoping rules. Most of my programming experience has been with shell, C, Python and Go. Most of these languages use lexical scoping but do so by the code block being executed. Javascript is a different animal when it comes to scoping. When I ran the following code to better understand scoping:

var foo = "String1";
console.log("Global: " + foo);
func1();

function func1() {
    var bar = "String2";
    console.log("Func1: " + foo + bar);
    func2();

    function func2() {
        var fmep = "String3";
        console.log("Func2: "  + foo + bar + fmep);
        func3();
    }
}

function func3() {
    var gorp = "String 4";
    console.log("Func3:" + foo + bar + fmep + gorp);
}

I originally thought node would spit out an error when func2() was executed. This was definitely not the case:

$ node test.js

Global: String1
Func1: String1String2
Func2: String1String2String3
/home/matty/test.js:19
	console.log("Func3:" + foo + bar + fmep + gorp);
	                             ^

ReferenceError: bar is not defined
    at func3 (/home/matty/test.js:19:31)
    at func2 (/home/matty/test.js:13:3)
    at func1 (/home/matty/test.js:8:2)
    at Object.<anonymous> (/home/matty/test.js:3:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)

In this case func2() ran just fine and func3() generated an exception when it tried to access the variable bar. But why is this? David Shariff wrote an excellent post describing scoping and javascript execution contexts which made my bug stick out like a sore thumb. The crux of the issue is that func3 is on the top of the execution context stack but it’s SCOPE is limited to the global execution context (see David’s awesome post for an illustrated example). I’m glad I figured this out early on in my javascript adventures. Adding this as a reference for myself.

This article was posted by Matty on 2017-11-30 09:50:43 -0500 EST