Scope and Execution Context in Javascript

Vivek
6 min readMay 22, 2019

--

One of the most basic and important concepts in javascript is scope and execution context. We should have better understanding of these concepts to understand the advanced concepts in javascript. In this post, we will try to demystify these concepts with popular interview questions.

Scope:

Scope determines the accessibility (visibility) of variables.In JavaScript there are two types of scope:

  • Global scope
  • Local scope

Global Scope:

If a variable is declared outside all functions or curly braces , it is said to be defined in the global scope. Variables in global scope can be accessed from everywhere in the application. Global variables are available for the lifetime of the application.

// Initialize a global variable
var globalName = "abc";

Local Scope:

Variables that are usable only in a specific part of your code are considered to be in a local scope. These variables are also called local variables. We can think of local scope as any new scope that we create within the global scope. In JavaScript, there are two kinds of local scope: function scope and block scope.

function localScopeExample(){
// LOCAL SCOPE
var name = 'xyz';
console.log(name); // Jerry
}
// GLOBAL SCOPE
console.log(name); // Uncaught ReferenceError: nameis not defined

Function Scope:

Each function written in JavaScript creates a new local scope. Variables defined in a function are visible everywhere within the function, but are not visible outside of the function.

// Global Scope
function functionScopeExample1() {
// Local Scope #1
function functionScopeExample2() {
// Local Scope #2
}
}

// Global Scope
function functionScopeExample3() {
// Local Scope #3
}
// Global Scope

Block Scope:

Block scope is defined with curly braces. ECMAScript 6 introduced the let and const keywords. Variables declared with let and const can have block scope. They can only be accessed in the block in which they are defined.

//Global Scope
let x = 1;
{
//Block Scope
let x = 2;
}
console.log(x); //1

var declaration has no block scope.

In the above example, if we replace let with var then the value of x will be 2.

(function blockScopeExample(){
for(var i=0; i<5; i++){
setTimeout(function logValue(){
console.log(i); //5.
}, 100);
}
})();

In the above example, the setTimeout function callback isn’t triggered until the for loop execution has completed. Since, var declaration has no block scope. When the for loop has finished executing the value of i is 5. Now when the setTimeout call begins to execute it uses the last set value of i which is 5. Hence 5 is printed in all the setTimeout callbacks.

However, if we declare variable i with let which has block scope, it creates a new variable locale to the block scope, for each iteration. The next loop code shows 0 1 2 3 4 5.

(function blockScopeExample(){
for(let i=0; i<5; i++){
setTimeout(function log(){
console.log(i); //0 1 2 3 4
}, 100);
}
})();

Let’s see another popular example:

const arr = [11, 22, 33, 44];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('Index: ' + i + ', element: ' + arr[i]);
}, 3000);
}

Output of above code will be: Index: 4, element: undefined(printed 4 times). We can use the concept used in previous question to solve this question.

Lexical Scope/Static Scope:

It is the ability of an inner function to access the scope of an outer function in which it is defined.

Functions are executed using the scope chain that was in effect when they were defined. - according to JavaScript Definition Guide

function outer()
{
let x = 5;

function inner()
{
console.log(x); // 5
}
inner();
}
outer();

Here, inner function can access the value of x defined in the outer function.

function outer() { 
var name = 'outer';
return function inner() {
console.log(name);
}
}
// returns the inner function const output = outer();
output(); // 'outer'

Execution Context:

The environment in which our code is running is Execution context. The Javascript engine creates a Global Execution Context every time we run some Javascript code. There are three types of execution context in JavaScript:

Global Execution Context

It is created before any code is executed.. The code that is not inside any function is in the global execution context. It performs two things: it creates a global object which is a window object (in the case of browsers) and sets the value of this to equal to the global object. There can only be one global execution context in a program.

Functional Execution Context

Whenever a function is executed (or called/invoked), a new execution context gets created. In the browser context, if the code is executing in strict mode value of this is undefined else it is window object in the function execution context.

Scope refers to the visibility of variables and context refers to the value of this in the same scope.

Eval Function Execution Context

It refers to Execution context inside eval function.

Execution Context Stack

It is a stack with a LIFO (Last in, First out) structure, which is used to store all the execution context created during the code execution.

function a(){ 
//function a Execution Context(EC)
b();
}

function b(){
//function b Execution Context
}
//Global Execution Context
a();

In the above example, first of all Global Execution Context (GEC) is going to be created. Then execution starts and interpreter encounters call to function a(), and here a new execution context is created and pushed on top EC Stack.

Anytime you invoke a function, a new EC is created & placed on top of EC Stack.

Now execution context for a() is created and interpreter will execute the code inside a() line-by-line. Then interpreter encounters call to function b(), this creates another EC which is pushed on top of EC stack of function a() . When b() finishes it will be popped-off the stack then a() finishes, its execution stack is removed from the stack and control reaches to the global execution context. Once all the code is executed, the JavaScript engine removes the global execution context from the current stack.

Let’s discuss few examples to understand the concept of Execution Context and value of ‘this’ in a given EC -

console.log(this === window);// true

Value of this in Global Execution Context by default is window object.

function a(){
console.log(this === window);// true
}
//GEC
a();

Calling a function in the GEC would have its this value aswindow . However, Calling a function that runs JavaScript statements in strict mode would have this as undefined.

var obj = {
a:1,
b:function(){
console.log(this);
}
}
obj.b()//{a: 1, b: ƒ}

Here, Function b() is one of the properties on object obj. When we call b() with reference to obj as obj.b(), it gets called in the context of obj.

var obj = {
a:1,
b:function(){
console.log(this);
}
}
var result = obj.b;
//GEC
result;// Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

In the above example, we are storing the reference of function b in variable result. If we execute this function at a later stage, it will run in the context from where it is called. In our example, we’re calling result in the global context, so it will have a window object as this reference.

Let’s use above concept and try to find out the output of below code:

var a = 2;var b = 3;var obj = {
a:1,
b:2,
add:function(){
console.log(this.a+this.b);
}
}
//calling function add with respect to object obj
obj.add();//3
var result = obj.add;
//GEC, var a and var b are defined on window object
result();// 5

Note: Always check the context in which the function has been called. Like,obj.add() has been called in the context of object obj and result() has been called in the context of window object.

this takes the reference of the immediate object calling the function

var a = 2;var b = 3;var obj = {
a:1,
b:2,
childObj:{
c:3,
add:function(){
console.log(this.a+' '+this.b+' '+this.c);
}
}
}
obj.childObj.add();// undefined undefined 3

In the above example, this refers to the immediate object childObj.

this behaves bit differently with arrow function. I will write different post on arrow function where I will try to cover the remaining concepts.

Stay tuned!

Explore the Series:

Please post any feedback, questions, or requests for topics.If this post was helpful, please click the clap 👏button below a few times to show your support.

--

--