In a previous blog, we learned scope chain, a part of Execution Context. We are still left with Variable Environment and this keyword. We will discuss this 2 topics in this blog.
Variable Environment
In the variable environment, variable declaration, functions, and arguments objects are stored. To understand the variable environment we have to understand Hoisting
.
Hoisting
Hoisting makes some types of variables usable in the code before they are actually declared. Before execution, code search for variable declaration, and for each new variable property is created called variable environment object.
EXAMPLE
console.log(age); // 21
var age = 21;
The table below will help you to understand what hoisting works for.
var variable
If we used var variable before the declaration in code it will work. Its initial value is undefined. Try below example.
console.log(age); // will print age i.e - 20
var age = 20;
let and const variable
let and var dont work before they are declared. They are hoisted but they are in TDZ (Temporary Dead Zone) which make its useful to work with let and const variable.
console.log(age); // Temporary Dead Zone (TDZ)
// it gives Reference Error: Cannot access 'a' before initialization
let age = 22;
Function Declaration
Normal functions created are hoisted. So before declaring function we can call and use it. Refre below example.
console.log(fun()); // print JavaScript
function fun(){
return "JavaScript";
}
Function Expression and arrow function
If we use let or const it gives an error with the message ReferenceError: Cannot access 'fun' before initialization
and if we use var it gives an error message as TypeError: fun is not a function
. Refer to the below example.
console.log(fun()); //ReferenceError: Cannot access 'fun' before initialization
let fun = function(){
return "JavaScript";
}
console.log(fun()); //TypeError: fun is not a function
var fun = function(){
return "JavaScript";
}
Why Hoisting?
It helps to use functions before they are declared. But this is not good practice. var is the by-product of hoisting. So usually we avoid using var for declaration.
When we use var for declaration then it creates property on the window object. So we avoid using var.
var age = 20;
console.log(age === window.age); // true
"this" Keyword
This keyword is created for every function execution context. this keyword is totally dependent on how it is called we will understand it with the help of an example.
"this" in method
When we use this in method it refers to the object itself.
let obj = {
name: "JavaScript",
birthYear: 1995;
calcAge: function(){
return 2022 - this.birthYear; // Same as obj.birthYear
}
}
"this" in simple function
When we use this in simple function it is undefined if we are using strict mode. If we are not using strict mode then it refer to window object.
With strict mode
'use strict';
function fun(){
console.log(this); // undefined
}
Without strict mode
function fun(){
console.log(this); // window object
}
"this" in arrow function
When using arrow function this is not owned by arrow function itself. But it uses this of its parent.
"this" in Event listener
when using this in Event listener it is window object.
Hope you understood everything in this 2 part blog series behind the scene of JavaScript.