Value of “this” in JavaScript… — Part 1

Seyed Sahil
8 min readJul 18, 2019

--

Hello, welcome to my new article on the JavaScript programming language. Today in this course we will see the usage of this keyword in JavaScript and some of the related topics like scopes, scope chain, execution context, closures, etc. I assume you have basic knowledge in JavaScript language and how it is being used in web development and if you like to get a quick overview of this keyword you are at the right place. When I looked at some of the source codes from the internet and from different projects I found it difficult to follow and catch this keyword. So I thought it would be nice to write about it. To avoid confusion, I have kept the actual keyword this reference in bold text or in quotes. Thank me later 🙂

Chapter 1: About Execution Context and Scope

Imagine you are sitting in a room and you have access to your book collection, personal laptop, your locker, art stuff, etc. So simply your room creates an environment inside your house. Now assume you have a WiFi connection set up outside the room and you know you can access it from your room. I think this example is enough to explain the execution context. Inside a room, you do a set of actions and these actions are done using different things that you have access to (you can use WiFi to browse the internet and you can create art using your art materials).

Execution Context and Scope

In JavaScript, an execution context is created when a function is invoked. In simple terms, we can say,

An execution context is a container or a room that holds the instructions, scope, and special this object.

In JavaScript, the scope is actually associated with functions. The scope is created along with a new function. In general, we can say,

Scope is created to control the visibility of variables defined inside a function. Variables defined inside a function will not be accessible outside the function.

Execution Stack or Call Stack

JavaScript is single-threaded means it linearly executes the program or executes code line by line. Whenever the engine encounters a new function call, it creates a new execution context along with the scope and place this inside a data structure and move the execution point to that function. Once the function execution is completed, the engine removes the execution context from the data structure and put back the execution point to the previous execution context. Simply,

A call stack or execution stack is a data structure that holds the execution context in the order of execution or simply it is a collection of active execution contexts.

JavaScript Code
Call Stack when the execution point is inside function A() (VS Code and Chrome)

Global Execution Context Functional Execution Context

In JavaScript file or inside a script tag in HTML file we can write directly executable codes or call functions or create variables and these are written at a very first level.

The default execution context created by engine, to execute globally accessible code is called as global execution context.

Considering a single program, there will be only one global execution context and this will be placed in the stack first time and removed when the execution point finishes the very last line.

I believe you know about the functional execution context now, but I would like to add one more point here.

The functional execution context has access to the global execution context of a program.

Okay. The above explanations are enough to understand the very first usage of this keyword. But I would like to explain a few more stuff.

Value Of “this” in Global and Functional Execution Context

In global execution context this will always points to the global object (window in browsers) and by default in functional execution context this will point to the global execution context.

Important: Strict mode won’t be covered in this article, will write about it in the new article and will not be a continuation of this part 🙂

Inner Functions or Function Nesting

In JavaScript, we can define a function inside another function or we can say the function nesting is possible. The functional execution context is created for inner functions too when it is called from an outer function execution context.

JavaScript Code
Function nesting, the scope when the execution point is inside function C() and output

From the output of the above program, it is clear that the inner function execution context has access to the outer function(s) it is enclosed in and the global execution context.

Creation and Execution Phase

We know that when a function is invoked an execution context will be created. This can be divided into two phases. Creation phase and execution phase.

In creation phase engine compiles the code, collect the information about the variables and function declarations.

Execution phase is where engine starts executing the code.

Chapter 2: Variable Object, Scope Chain and Closure

Anonymous Functions and Function Expressions

It is clear from the headline what I am going to talk about.

A function definition that doesn’t have a name is called an anonymous function.

In JavaScript, we can assign a function to a variable or pass it as a function argument or immediately execute it after defining it.

When we use a function as part of a larger expression we can say it formed a function expression.

JavaScript Code
Use of anonymous function and named function along with function expression

Invoking a named function or anonymous function immediately after defining it is called Immediately Invoked Function Expression (IIFE)

Closures

Actually, information about closures is explained in one of my previous article s about JavaScript. Take a look at the explanation there. Don’t look at the code for now 🙂

Hoisting

In JavaScript, in an active scope, you can use a variable or call a function before actual declaration or definition. The engine hoists the variable declaration and function definition and moves it to the beginning of the scope during the creation phase.

Variables declaration and function definitions will be hoisted in the active scope before actual execution.

JavaScript had no support for block scope, which means variables declared inside statement blocks like if, while, for, etc too will be hoisted to functional scope beginning. But with ES6 version two new keywords introduced and these are called let and const. These two are used to declare variables only, but if they are inside a block, this will not be hoisted to functional scope level, but to block scope level. Take a look at the below program.

JavaScript Code
How hoisting works in JavaScript and output of the program

Let us go through the scopes in this program.

  • Scope created for function A() and global scope.
  • Block scope created for the for loop, Say.
  • Unnamed scope created for the block which is after function B() definition.
  • Scope created for function B().

Okay, let’s talk about the hoisting process

  • Variable i in for loop will be hoisted to function A()
  • function B() inside for loop will be hoisted to function A(). This is the reason it is possible to invoke from outside for loop.
  • Variable x will be hoisted to the for loop statement block initialization part. This is the reason why x value gets incremented by i value and not initialized every time inside the loop.
  • Variable y will be hoisted to the unnamed block and will not be accessible from outer scopes. And every time this block scope will be created by the engine. This is why we see y value printed with for loop iteration.

Now it is time for you to do a small exercise on the scope. Are you thinking about any specific scenario? Then open a console and start testing it out. for example, try to execute the commented code.

Value Of “this” in Block Scopes

By default in blocks this will always point to global object which is our browser window.

Important: Arrow functions and their usage along with the lexical scoping will be covered later in the next part, be patient 🙂

Variable Object

We can say a variable object is a special container object created by the engine to store the variables and function declarations in of functional execution context.

One point to note here is the function expressions. Variable objects are managed by the engine and are not accessible in our program and function expressions will not be stored in the variable object.

Activation Object

An activation object is created when we call a function and is similar to the variable object. But it will store the arguments and formal parameters of that function.

Activation object contains two special objects and they are called this and arguments.

Scope Chain

JavaScript Code
State of the program when the execution point reaches Line 16

Take a look at the above-given image, what you see below the call stack is a list of active scopes. The output of the program will be ‘NaN’ — a special value which stands for Not a Number. How this happened? That is for you to find 🙂

A scope chain is simply a stack-like data structure containing all accessible scopes from the current execution context until the global execution context. Each of the execution context will have the scope chain as a special object.

Taking the above program as an example, say the execution point reached line 16. Let’s see how the lookup happens with the help of the scope chain.

So, here we have the scope of the function D() one top of the chain.

Variable N is available as a formal parameter and is available in the same scope -Done

Variable C is available in the scope of function C() we need a lookup through the scope chain of the execution context of function D(). The closures come at this point. Closures act as a link between two scopes. If you see the above scope chain function D() scope has access to function A() scope and function C() scope. Like a 1 to N mapping. Variable C is available in function C() scope and you can see this by expanding the Closure(C) in developer tools.

Variable B is available at function A() scope and as I mentioned above the lookup happens using the closures. One thing to note here is the value of B at this point will be undefined and this is the reason we get the output as NaN. (Remember hoisting ?)

Part 1 ends here…

Originally published at http://sydlabz.wordpress.com on July 18, 2019.

--

--

Seyed Sahil
Seyed Sahil

Written by Seyed Sahil

Coding Since 2011, Software Engineer, Game Developer, Artist, Photographer. Passionate about Security and Web Technologies. Favourites — C, Java, Javascript.

No responses yet