How to use Static and Dynamic Scope – JavaScript

We can define the scope of a variable by scope defining keywords and lexical structures that define static and dynamic scope of variables in JavaScript.

We are mostly familiar with two types of scope, i.e. static and dynamic, where we presume that most variable have a static scope. However, there is another less popular scope type, the runtime augmented variable. Let us go throw importance these different scopes have in JavaScript.

Static scope

Static scope has lexical scoping. It is useful in modern programming languages and helps assign a scope to a range of functions or variables. All variables within the particular block, have their scope only within the block we declare them. The concept of closures (brackets) is used in static scopes.

Variables declared with static scopes are also called private variables. A variable’s lexical (static) scope gets defined when it is created. Its scope is determined by the lexical structure (use of brackets) in the code. Variables declared within a specific block of code, inside closure brackets are accessible only within that space.

In lexical (static) scopes the innermost and outermost functions can access all variables from the parent scopes. For example, a variable inside a function has multiple if else loops with curly braces and a lexical structure. We can access it within all these loops. As we declared it in the parent loop. However, a child variable is lexically bound to the parent function. As a variable declared inside a function cannot be accessed by the surrounding function. Unless we pass it as a parameter along with a function call, that too within the specific function’s scope. JavaScript and many other modern programming languages like R, Haskell, ML, and Dart offer lexical (static) scopes.

Let’s go through an example of lexical (static) scoping in JavaScript.

var x = 20
var func = function (){
var y = 40;
    console.log("x and y is accessible (outside function):", x, y);
    var insideFunc= function (){
        var z = 60;
        console.log("x and y and z is accessible (inside):", x, y, z);
    }
    insideFunc();
    return;
}
func();
console.log("only x is accessible (global):", x); // as it is declared outside all functions (not bound to function scope)

In the code above, x is a variable which can be accessed by all function scopes since has a global scope. However, variable y is of local scope for the function assigned to the variable func and it cannot be accessible outside that function. The inner functions are lexically bound by the outer functions, and can access both variables y and z.

Dynamic Scope

Dynamic Scoping is the runtime state of the program stack that will determine what variable you are referring to. It is the opposite approach to static scoping. It will access variables that can be called from outside the block of code in which they are defined. These are sometimes referred as public variables.

Dynamic scoping takes the latest value assigned to a variable. So, whenever a new function gets executed, a new scope gets pushed onto the stack. It works as a global identifier.

Dynamic scopes are not common in modern languages. However, dynamically scoped languages also exist, for example original versions of Bash, Lisp, Perl and Latex.

function x() { 
    console.log(i);
}

function y() {
    var i = 1;
    x();
}

var i = 0;

y();

The code above shows two functions, x and yHere x logs out the value of i which is globally set to 0. While y sets its value to 1, and makes a call to x. If we call y, it consoles 0. This is because — while x doesn’t have a variable called i — x has access to the enclosing scope where the function is defined. And in the global scope, we have an i which is set to 0. This is static scoping.

In dynamic scoping, the value of i will be 1. This is because instead of checking the place where the function is defined, it looks for where it is called from. It checks from the call stack that it has been called from y, which then sets the value of i to be 1.