- Note :
JavaScript is a Synchronous Single Threaded Language
Execution Context in Js
Execution context is the environment in which the JavaScript code is executed. It is the place where all the variables and functions are defined.
Global Execution Context
The global execution context is the execution context in which the code is executed when it is loaded in the browser. The global execution context is also called the global object.
Phases in Execution Context (Code Execution)
- Creation of Execution Context - Memory allocation and initialization of variables and functions.
- Execution of Code - Execution of the code.
- Destruction of Execution Context - Memory deallocation (Garbage Collection)
Execution Context explained w/ Code
var a = 2;
var b = 3;
function add(m, n) {
var sum = m + n;
return sum;
}
var sum1 = add(1, 2);
var sum2 = add(a, b);
console.log(sum1);
console.log(sum2);
Execution Context explained w/o Code
Example of Execution Context : Square Function
var n = 2;
function square(n) {
return n * n;
}
var sq1 = square(n);
var sq2 = square(2);
console.log(sq1);
console.log(sq2);
Flow in Execution Context
- first the global execution context is created
- then the function is executed
- then the local execution context is created
- then the local execution context is destroyed
- then the global execution context is destroyed
Resources to read about Execution Context
Hoisting : Hoisting is JavaScript's default behavior of moving declarations to the top.
- Hoisting is the process of moving declarations to the top of the current scope.
- Its is relative to the current execution context.
- It is a JavaScript feature that allows you to declare a variable before you use it.
Hoisting in JavaScript
console.log(a);
var a = 2;
greet();
function greet() {
console.log("Hello!");
}
Output :
undefined
Hello!
Understanding Hoisting | Example (Illustrated with Execution Context in Phase 1 and Phase 2)
Temporal Dead Zone | Good Practices
- Good practice is to avoid using the temporal dead zone. (Scoping rules, accessibility, etc.)
- Temporal dead zone is a feature of JavaScript that allows you to declare a variable before you use it.
let
andconst
are not hoisted and when accessed before declaration, it throws an error.
console.log(a); // undefined -> a is not defined (not hoisted)
const a = 2;
The thing with
var
is that it is hoisted. It was introduced inES5
, which was beforelet
andconst
.
Resources to read about Temporal Dead Zone
Data Types in JavaScript
There are 2 categories of data types in JavaScript
- Primitive type
- Reference type
Primitive types are:
- Number :
1
,1.5
,0
,-1
,-1.5
,Infinity
,-Infinity
,NaN
- String :
"Hello"
,'Hello'
,"1"
,'1'
- Boolean :
true
,false
- Symbol :
Symbol()
- Undefined :
undefined
- Null :
null
- NaN :
NaN
Reference types are:
- Object :
{}
,new Object()
- Array :
[]
,new Array()
- Function :
function() {}
- Date :
new Date()
- RegExp :
/\w+/
- Error :
new Error()
- Map :
new Map()
- Set :
new Set()
- WeakMap :
new WeakMap()
- WeakSet :
new WeakSet()
Excercise : Data Types
let a = "Hello";
console.log(a, typeof a);
let b = 2.5;
console.log(b, typeof b);
let c = true;
console.log(c, typeof c);
let d = undefined;
console.log(d, typeof d);
let e = null; // a bug in js which hasnt been fixed yet
console.log(e, typeof e); // null is a primitive type still has a typeof object
Output :
Hello string
2.5 number
true boolean
undefined undefined
null object
A good read/research on null being a typeof object in JavaScript : the
missing object
Refrence Data Types in JavaScript
let arr = [1, 2, 3];
console.log(arr, typeof arr);
let obj = {
name: "John",
age: 30,
};
console.log(obj, typeof obj);
function greet(name) {
console.log("Hello", name);
}
console.log(greet, typeof greet);
Output :
[ 1, 2, 3 ] object
{ name: 'John', age: 30 } object
[Function: greet] function
- Note :
- Primitive Datatypes gets stored in
Stack Memory
. - Refrence Datatypes gets stored in
Heap Memory
.
- Primitive Datatypes gets stored in
Excercise : Primitive Data Types & Stack Memory | Access by value
let firstPerson = "Hitesh";
let secondPerson = firstPerson; // copy
firstPerson = "Arshad"; // change
console.log(firstPerson, secondPerson); // Hitesh Arshad
Output :
Hitesh Arshad
Illustrating access by value :
firstPerson
is a copy ofsecondPerson
Stack is
LIFO (Last In First Out)
Refrence Data Types & Concept of access by reference
let fp = {
name: "Hitesh",
age: 30,
};
let sp = fp; // copy
fp.name = "Arshad"; // change
console.log(fp, sp); // { name: 'Arshad', age: 30 } { name: 'Arshad', age: 30 }
Output :
{ name: 'Arshad', age: 30 } { name: 'Arshad', age: 30 }
Refrence Datatypes use Heap Memory
(Access by reference)
- Solutions to the above problem :
spread operator
,object.assign
,deep copy
,shallow copy
spread operator
:...
object.assign
:Object.assign()
deep copy
:JSON.parse(JSON.stringify(obj))
shallow copy
:Object.assign({}, obj)
Altough Js is synchronous, it is possible to make asynchronous calls in JavaScript.
- AJAX is an example of asynchronous call.
- AJAX stands for Asynchronous JavaScript and XML.
- Callbacks, Promises and Async/Await are some of the ways to make asynchronous calls in JavaScript.