Namaste JavaScript Notes
Namaste JavaScript Notes
Everything in JS happens inside the execution context. Imagine a sealed-off container inside
which JS runs. It is an abstract concept that hold info about the env. within the current code
is being executed.
In the container the first component is memory component and the 2nd one is code
component
Memory component has all the variables and functions in key value pairs. It is also called
Variable environment.
Code component is the place where code is executed one line at a time. It is also called the
Thread of Execution.
JS is a synchronous, single-threaded language
var n = 2;
function square(num) {
return ans;
The very first thing which JS does is memory creation phase, so it goes to line one of above
code snippet, and allocates a memory space for variable 'n' and then goes to line two, and
allocates a memory space for function 'square'. When allocating memory for n it stores
'undefined', a special value for 'n'. For 'square', it stores the whole code of the function
inside its memory space. Then, as square2 and square4 are variables as well, it allocates
memory and stores 'undefined' for them, and this is the end of first phase i.e. memory creation
phase.
Now, in 2nd phase i.e. code execution phase, it starts going through the whole code line by
line. As it encounters var n = 2, it assigns 2 to 'n'. Until now, the value of 'n' was undefined. For
function, there is nothing to execute. As these lines were already dealt with in memory creation
phase.
Coming to line 6 i.e. var square2 = square(n), here functions are a bit different than any
other language. A new execution context is created altogether. Again in this new
execution context, in memory creation phase, we allocate memory to num and ans the two
variables. And undefined is placed in them. Now, in code execution phase of this execution
context, first 2 is assigned to num. Then var ans = num * num will store 4 in ans. After that,
return ans returns the control of program back to where this function was invoked from.
When return keyword is encountered, It returns the control to the called line and also the
function execution context is deleted.
Same thing will be repeated for square4 and then
after that is finished, the global execution context will be destroyed.
So the final diagram
before deletion would look something like:
Javascript manages code execution context creation and deletion with the the help of Call
Stack.
Call Stack is a mechanism to keep track of its place in script that calls multiple function.
Call Stack maintains the order of execution of execution contexts. It is also known as
Program Stack, Control Stack, Runtime stack, Machine Stack, Execution context stack.
Watch Live On Youtube below:
console.log(x); // undefined
var x = 7;
function getName() {
console.log("Namaste Javascript");
It should have been an outright error in many other languages, as it is not possible to even
access something which is not even created (defined) yet But in JS, We know that in
memory creation phase it assigns undefined and puts the content of function to function's
memory. And in execution, it then executes whatever is asked. Here, as execution goes line
by line and not after compiling, it could only print undefined and nothing else. This
phenomenon, is not an error. However, if we remove var x = 7; then it gives error. Uncaught
ReferenceError: x is not defined
Hoisting is a concept which enables us to extract values of variables and functions even
before initialising/assigning value without getting error and this is happening due to the 1st
phase (memory creation phase) of the Execution Context.
So in previous lecture, we learnt that execution context gets created in two phase, so even
before code execution, memory is created so in case of variable, it will be initialized as
undefined while in case of function the whole function code is placed in the memory.
Example:
function getName(){
console.log("Namaste JavaScript");
Now let's observe a different example and try to understand the output.
console.log(getName);
console.log("Namaste JavaScript");
// The code won't execute as the first line itself throws an TypeError.
a();
b(); // we are calling the functions before defining them. This will work
properly, as seen in Hoisting.
console.log(x);
function a() {
console.log(x);
function b() {
var x = 100;
console.log(x);
Outputs:
10
100
In first phase of GEC (memory phase), variable x:undefined and a and b have their entire
function code as value initialized
In second phase of GEC (execution phase), when the function is called, a new local
Execution Context is created. After x = 1 assigned to GEC x, a() is called. So local EC for a
is made inside code part of GEC.
For local EC, a totally different x variable assigned undefined(x inside a()) in phase 1 , and in
phase 2 it is assigned 10 and printed in console log. After printing, no more commands to
run, so a() local EC is removed from both GEC and from Call stack
Call Stack :[GEC, b()] -> GEC (after printing yet another totally different x value as 100 in
console log)
Finally GEC is deleted and also removed from call stack. Program ends.
reference:
eg:
var x = 10;
console.log(x); // 10
console.log(this.x); // 10
console.log(window.x); // 10
When variable is declared but not assigned value, its current value is undefined. But when
the variable itself is not declared but called in code, then it is not defined.
console.log(x); // undefined
var x = 25;
console.log(x); // 25
JS is a loosely typed / weakly typed language. It doesn't attach variables to any datatype.
We can say var a = 5, and then change the value to boolean a = true or string a = 'hello' later
on.
Never assign undefined to a variable manually. Let it happen on it's own accord.
// CASE 1
function a() {
console.log(b); // 10
var b = 10;
a();
// CASE 2
function a() {
c();
function c() {
console.log(b); // 10
var b = 10;
a();
// CASE 3
function a() {
c();
function c() {
var b = 100;
console.log(b); // 100
var b = 10;
a();
// CASE 4
function a() {
var b = 10;
c();
function c() {
console.log(b); // 10
a();
Now lets also assign the memory sections of each execution context in call_stack.
So, Lexical Environment = local memory + lexical env of its parent. Hence, Lexical
Environement is the local memory along with the lexical environment of its parent
Lexical: In hierarchy, In order
Whenever an Execution Context is created, a Lexical environment(LE) is also created and is
referenced in the local Execution Context(in memory space).
The process of going one by one to parent and checking for values is called scope chain or
Lexcial environment chain.
function a() {
function c() {
// logic here
Lexical or Static scope refers to the accessibility of variables, functions and object based on
phylical location in source code.
Global {
Outer {
Inner
TLDR; An inner function can access variables which are in outer functions even if inner
function is nested deep. In any other case, a function can't access variables not in its scope.
let a = 10;
console.log(a); // 10
var b = 15;
console.log(window.a); // undefined
console.log(window.b); // 15
Both a and b are actually initialized as undefined in hoisting stage. But var b is inside the
storage space of GLOBAL, and a is in a separate memory object called script, where it can
be accessed only after assigning some value to it first ie. one can access 'a' only if it is
assigned. Thus, it throws error.
Temporal Dead Zone : Time since when the let variable was hoisted until it is initialized
some value.
let a = 10;
------------------
let a = 10;
var a = 100; // this code also rejected upfront as SyntaxError. (can't use same
name in same scope)
Let is a stricter version of var. Now, const is even more stricter than let.
let a;
a = 10;
------------------
const b;
b = 10;
------------------
const b = 100;
This Error signifies that x has never been in the scope of the program. This literally
means that x was never defined/declared and is being tried to be accesed.
Uncaught ReferenceError: cannot access 'a' before initialization
This Error signifies that 'a' cannot be accessed because it is declared as 'let' and
since it is not assigned a value, it is its Temporal Dead Zone. Thus, this error occurs.
Uncaught SyntaxError: Identifier 'a' has already been declared
This Error signifies that we are redeclaring a variable that is 'let' declared. No
execution will take place.
Uncaught SyntaxError: Missing initializer in const declaration
Block aka compound statement is used to group JS statements together into 1 group. We
group them within {...}
var a = 10;
let b = 20;
const c = 30;
var a = 10;
let b = 20;
const c = 30;
console.log(a); // 10
* Reason?
* Thus we say, *let* and *const* are BLOCK SCOPED. They are stored in a
separate mem space which is reserved for this block. Also, they can't be accessed
outside this block. But var a can be accessed anywhere as it is in global scope.
Thus, we can't access them outside the Block.
What is Shadowing?
var a = 100;
let b = 20;
const c = 30;
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
console.log(a); // 10, instead of the 100 we were expecting. So block "a" modified
val of global "a" as well. In console, only b and c are in block space. a
initially is in global space(a = 100), and when a = 10 line is run, a is not
created in block space, but replaces 100 with 10 in global space itself.
So, If one has same named variable outside the block, the variable inside the block shadows
the outside variable. This happens only for var
Let's observe the behaviour in case of let and const and understand it's reason.
let b = 100;
var a = 10;
let b = 20;
const c = 30;
console.log(b); // 20
console.log(b); // 100, Both b's are in separate spaces (one in Block(20) and one
in Script(another arbitrary mem space)(100)). Same is also true for *const*
declarations.
Same logic is true even for functions
const c = 100;
function x() {
const c = 10;
console.log(c); // 10
x();
console.log(c); // 100
let a = 20;
var a = 20;
We cannot shadow let with var. But it is valid to shadow a let using a let. However, we can
shadow var with let.
All scope rules that work in function are same in arrow functions too.
Since var is function scoped, it is not a problem with the code below.
let a = 20;
function x() {
var a = 20;
Episode 10 : Closures in JS
Function bundled along with it's lexical scope is closure.
JavaScript has a lexcial scope environment. If a function needs to access a variable, it first
goes to its local memory. When it does not find it there, it goes to the memory of its lexical
parent. See Below code, Over here function y along with its lexical scope i.e. (function x)
would be called a closure.
function x() {
var a = 7;
function y() {
console.log(a);
return y;
var z = x();
In above code, When y is returned, not only is the function returned but the entire closure
(fun y + its lexical scope) is returned and put inside z. So when z is used somewhere
else in program, it still remembers var a inside x()
Thus In simple words, we can say:
A closure is a function that has access to its outer function scope even after the
function has returned. Meaning, A closure can remember and access variables and
arguments reference of its outer function even after the function has returned.
Advantages of Closure:
function x() {
var i = 1;
setTimeout(function() {
console.log(i);
}, 3000);
console.log("Namaste Javascript");
x();
// Output:
// Namaste Javascript
We expect JS to wait 3 sec, print 1 and then go down and print the string. But JS prints string
immediately, waits 3 sec and then prints 1.
The function inside setTimeout forms a closure (remembers reference to i). So wherever
function goes it carries this ref along with it.
setTimeout takes this callback function & attaches timer of 3000ms and stores it. Goes to
next line without waiting and prints string.
After 3000ms runs out, JS takes function, puts it into call stack and runs it.
Q: Print 1 after 1 sec, 2 after 2 sec till 5 : Tricky interview question
function x() {
setTimeout(function() {
console.log(i);
}, i*1000);
console.log("Namaste Javascript");
x();
// Output:
// Namaste Javascript
// 6
// 6
// 6
// 6
// 6
Reason?
This happens because of closures. When setTimeout stores the function somewhere
and attaches timer to it, the function remembers its reference to i, not value of i. All
5 copies of function point to same reference of i. JS stores these 5 functions, prints
string and then comes back to the functions. By then the timer has run fully. And due
to looping, the i value became 6. And when the callback fun runs the variable i = 6.
So same 6 is printed in each log
To avoid this, we can use let instead of var as let has Block scope. For each
iteration, the i is a new variable altogether(new copy of i). Everytime setTimeout is
run, the inside function forms closure with new variable i
But what if interviewer ask us to implement using var?
function x() {
function close(i) {
setTimeout(function() {
console.log(i);
}, i*1000);
close(i); // everytime you call close(i) it creates new copy of i. Only this
time, it is with var itself!
console.log("Namaste Javascript");
x();
function outer() {
var a = 10;
function inner() {
console.log(a);
return inner;
outer()(); // 10 // over here first `()` will return inner function and then using
secong `()` to call inner function
function inner() {
console.log(a);
var a = 10;
return inner;
outer()(); // 10
Ans: Yes, because inner function forms a closure with its outer environment so sequence
doesn't matter.
function outer() {
let a = 10;
function inner() {
console.log(a);
return inner;
outer()(); // 10
Q4: Will inner function have the access to outer function argument?
function outer(str) {
let a = 10;
function inner() {
console.log(a, str);
return inner;
Ans: Inner function will now form closure and will have access to both a and b.
function outest() {
var c = 20;
function outer(str) {
let a = 10;
function inner() {
console.log(a, c, str);
return inner;
return outer;
function outest() {
var c = 20;
function outer(str) {
let a = 10;
function inner() {
console.log(a, c, str);
return inner;
return outer;
let a = 100;
Ans: Still the same output, the inner function will have reference to inner a, so conflicting name
won't matter here. If it wouldn't have find a inside outer function then it would have went more
outer to find a and thus have printed 100. So, it try to resolve variable in scope chain and if a
wouldn't have been found it would have given reference error.
var count = 0;
function increment(){
count++;
// in the above code, anyone can access count and change it.
------------------------------------------------------------------
function counter() {
var count = 0;
function increment(){
count++;
------------------------------------------------------------------
function counter() {
var count = 0;
count++;
console.log(count);
var counter1 = counter(); //counter function has closure with count var.
counter2(); // here counter2 is whole new copy of counter function and it wont
impack the output of counter1
*************************
// Above code is not good and scalable for say, when you plan to implement
decrement counter at a later stage.
function Counter() {
var count = 0;
count++;
console.log(count);
this.decrementCounter = function() {
count--;
console.log(count);
counter1.incrementCounter();
counter1.incrementCounter();
counter1.decrementCounter();
// returns 1 2 1
function a() {
var x = 0;
console.log(x);
y();
// Once a() is called, its element x should be garbage collected ideally. But fun
b has closure over var x. So mem of x cannot be freed. Like this if more closures
formed, it becomes an issue. To tacke this, JS engines like v8 and Chrome have
smart garbage collection mechanisms. Say we have var x = 0, z = 10 in above code.
When console log happens, x is printed as 0 but z is removed automatically.
function a() {
console.log("Hello");
a(); // Hello
var b = function() {
console.log("Hello");
b();
b(); // TypeError
function a() {
console.log("Hello A");
var b = function() {
console.log("Hello B");
// Why? During mem creation phase a is created in memory and function assigned to
a. But b is created like a variable (b:undefined) and until code reaches the
function() part, it is still undefined. So it cannot be called.
function () {
}// this is going to throw Syntax Error - Function Statement requires function
name.
They don't have their own identity. So an anonymous function without code inside it results in
an error.
Anonymous functions are used when functions are used as values eg. the code sample for
function expression above.
console.log("b called");
Q: Parameters vs Arguments?
console.log("b called");
b(function(){});
var b = function(param1) {
console.log(param1);
function xyz(){
var b = function(param1) {
return function() {
setTimeout(function () {
console.log("Timer");
JS is a synchronous and single threaded language. But due to callbacks, we can do async
things in JS.
setTimeout(function () {
console.log("timer");
}, 5000);
function x(y) {
console.log("x");
y();
x(function y() {
console.log("y");
});
// x y timer
In the call stack, first x and y are present. After code execution, they go away and stack is
empty. Then after 5 seconds (from beginning) anonymous suddenly appear up in stack ie.
setTimeout
All 3 functions are executed through call stack. If any operation blocks the call stack, its
called blocking the main thread.
Say if x() takes 30 sec to run, then JS has to wait for it to finish as it has only 1 call stack/1
main thread. Never block main thread.
Always use async for functions that take time eg. setTimeout
// Another Example of callback
setTimeout(() => {
console.log(str);
cb();
}, Math.floor(Math.random() * 100) + 1)
function printAll() {
printStr("A", () => {
printStr("B", () => {
})
})
printAll() // A B C // in order
Event Listener
// index.html
// in index.js
console.log("Button clicked");
});
let count = 0;
});
let count = 0;
});
attachEventList();
Event listeners are heavy as they form closures. So even when call stack is empty,
EventListener won't free up memory allocated to count as it doesn't know when it may need
count again. So we remove event listeners when we don't need them (garbage collected)
onClick, onHover, onScroll all in a page can slow it down heavily.
Browser has JS Engine which has Call Stack which has Global execution context, local
execution context etc.
But browser has many other superpowers - Local storage space, Timer, place to enter
URL, Bluetooth access, Geolocation access and so on.
Now JS needs some way to connect the callstack with all these superpowers. This is
done using Web APIs.
WebAPIs
None of the below are part of Javascript! These are extra superpowers that browser has.
Browser gives access to JS callstack to use these powers.
setTimeout(), DOM APIs, fetch(), localstorage, console (yes, even console.log is not JS!!),
location and so many more.
console.log("start");
setTimeout(function cb() {
console.log("timer");
}, 5000);
console.log("end");
cb() cannot simply directly go to callstack to be execeuted. It goes through the callback
queue when timer expires.
Event loop keep checking the callback queue, and see if it has any element to puts it into call
stack. It is like a gate keeper.
Once cb() is in callback queue, eventloop pushes it to callstack to run. Console API is used
and log printed
Q: Another example to understand Eventloop & Callback Queue.
See the below Image and code and try to understand the reason:
Explaination?
console.log("Start");
// cb() registered inside webapi environment and event(click) attached to it. i.e.
REGISTERING CALLBACK AND ATTACHING EVENT TO IT.
console.log("Callback");
});
console.log("End"); // calls console api and logs in console window. After this GEC get
removed from call stack.
// In above code, even after console prints "Start" and "End" and pops GEC out, the
eventListener stays in webapi env(with hope that user may click it some day) until
explicitly removed, or the browser is closed.
Eventloop has just one job to keep checking callback queue and if found something push it
to call stack and delete from callback queue.
Ans: Suppose user clciks button x6 times. So 6 cb() are put inside callback queue. Event loop
sees if call stack is empty/has space and whether callback queue is not empty(6 elements
here). Elements of callback queue popped off, put in callstack, executed and then popped off
from call stack.
setTimeout(function cbT() {
console.log("CB Timeout");
}, 5000);
fetch("https://api.netflix.com").then(function cbF() {
console.log("CB Netflix");
console.log("End");
Code Explaination:
* fetch registers cbF into webapi environment along with existing cbT.
* cbT is waiting for 5000ms to end so that it can be put inside callback queue.
cbF is waiting for data to be returned from Netflix servers gonna take 2 seconds.
* After this millions of lines of code is running, by the time millions line of
code will execute, 5 seconds has finished and now the timer has expired and
response from Netflix server is ready.
* Data back from cbF ready to be executed gets stored into something called a
Microtask Queue.
* Microtask Queue is exactly same as Callback Queue, but it has higher priority.
Functions in Microtask Queue are executed earlier than Callback Queue.
* In console, first Start and End are printed in console. First cbF goes in
callstack and "CB Netflix" is printed. cbF popped from callstack. Next cbT is
removed from callback Queue, put in Call Stack, "CB Timeout" is printed, and cbT
removed from callstack.
All the callback functions that come through promises go in microtask Queue.
Mutation Observer : Keeps on checking whether there is mutation in DOM tree or not, and
if there, then it execeutes some callback function.
Callback functions that come through promises and mutation observer go inside Microtask
Queue.
All the rest goes inside Callback Queue aka. Task Queue.
If the task in microtask Queue keeps creating new tasks in the queue, element in callback
queue never gets chance to be run. This is called starvation
1. When does the event loop actually start ? - Event loop, as the name suggests, is a
single-thread, loop that is almost infinite. It's always running and doing its job.
2. Are only asynchronous web api callbacks are registered in web api environment? -
YES, the synchronous callback functions like what we pass inside map, filter and reduce
aren't registered in the Web API environment. It's just those async callback functions which
go through all this.
3. Does the web API environment stores only the callback function and pushes the
same callback to queue/microtask queue? - Yes, the callback functions are stored, and
a reference is scheduled in the queues. Moreover, in the case of event listeners(for
example click handlers), the original callbacks stay in the web API environment forever,
that's why it's adviced to explicitly remove the listeners when not in use so that the garbage
collector does its job.
4. How does it matter if we delay for setTimeout would be 0ms. Then callback will move
to queue without any wait ? - No, there are trust issues with setTimeout() 😅. The
callback function needs to wait until the Call Stack is empty. So the 0 ms callback might
have to wait for 100ms also if the stack is busy.
1. Parsing - Code is broken down into tokens. In "let a = 7" -> let, a, =, 7 are all tokens.
Also we have a syntax parser that takes code and converts it into an AST (Abstract
Syntax Tree) which is a JSON with all key values like type, start, end, body etc (looks like
package.json but for a line of code in JS. Kinda unimportant)(Check out astexplorer.net -
> converts line of code into AST).
2. Compilation - JS has something called Just-in-time(JIT) Compilation - uses both
interpreter & compiler. Also compilation and execution both go hand in hand. The AST
from previous step goes to interpreter which converts hi-level code to byte code and
moves to execeution. While interpreting, compiler also works hand in hand to compile
and form optimized code during runtime. Does JavaScript really Compiles? The
answer is a loud YES. More info at: Link 1, Link 2, Link 3. JS used to be only interpreter
in old times, but now has both to compile and interpreter code and this make JS a JIT
compiled language, its like best of both world.
3. Execution - Needs 2 components ie. Memory heap(place where all memory is stored)
and Call Stack(same call stack from prev episodes). There is also a garbage collector. It
uses an algo called Mark and Sweep.
GiF Demo
Companies use different JS engines and each try to make theirs the best.
v8 of Google has Interpreter called Ignition, a compiler called Turbo Fan and garbage
collector called Orinoco
v8 architecture:
console.log("Start");
setTimeout(function cb() {
console.log("Callback");
}, 5000);
console.log("End");
// o/p: Over here setTimeout exactly doesn't guarantee that the callback function will
be called exactly after 5s. Maybe 6,7 or even 10! It all depends on callstack. Why?
Reason?
setTimeout guarantees that it will take at least the given timer to execute the code.
JS is a synchronous single threaded language. With just 1 thread it runs all pieces of code. It
becomes kind of an interpreter language, and runs code very fast inside browser (no need to
wait for code to be compiled) (JIT - Just in time compilation). And there are still ways to do
async operations as well.
What if timeout = 0sec?
console.log("Start");
setTimeout(function cb() {
console.log("Callback");
}, 0);
console.log("End");
// Even though timer = 0s, the cb() has to go through the queue. Registers calback in
webapi's env , moves to callback queue, and execute once callstack is empty.
// This method of putting timer = 0, can be used to defer a less imp function by a
little so the more important function(here printing "End") can take place
function x() {
console.log("Hi)";
};
function y(x) {
x();
};
y(); // Hi
// x is a callback function
First Approach:
const radius = [1, 2, 3, 4];
return output;
console.log(calculateArea(radius));
The above solution works perfectly fine but what if we have now requirement to calculate array
of circumference. Code now be like
return output;
console.log(calculateCircumference(radius));
But over here we are violating some principle like DRY Principle, now lets observe the better
approach.
const radiusArr = [1, 2, 3, 4];
output.push(operation(radiusArr[i]));
return output;
console.log(calculate(radiusArr, area));
console.log(calculate(radiusArr, circumference));
// Over here we have extracted logic into separate functions. This is the beauty
of functional programming.
Polyfill of map
***************************************************
Lets convert above calculate function as map function and try to use. So,
Array.prototype.calculate = function(operation) {
output.push(operation(this[i]));
return output;
console.log(radiusArr.calculate(area))
Map function
It is basically used to transform a array. The map() method creates a new array with the results
of calling a function for every array element.
const output = arr.map(function) // this function tells map that what transformation I want on
each element of array
function double(x) {
return x * 2;
const doubleArr = arr.map(double); // Internally map will run double function for
each element of array and create a new array and returns it.
// Transformation logic
function triple(x) {
return x * 3;
// Transformation logic:
function binary(x) {
return x.toString(2);
return x.toString(2);
So basically map function is mapping each and every value and transforming it based on given
condition.
Filter function
Filter function is basically used to filter the value inside an array. The arr.filter() method is used
to create a new array from a given array consisting of only those elements from the given array
which satisfy a condition set by the argument method.
return x % 2;
Filter function creates an array and store only those values which evaluates to true.
Reduce function
It is a function which take all the values of array and gives a single output of it. It reduces the
array to give a single output.
const array = [5, 1, 3, 2, 6];
let sum = 0;
return sum;
console.log(findSum(array)); // 17
return accumulator;
}, 0); //In above example sum was initialized with 0, so over here accumulator
also needs to be initialized, so the second argument to reduce function represent
the initialization value.
console.log(sumOfElem); // 17
// find max inside array: Non functional programming way:
function findMax(arr) {
let max = 0;
max = arr[i]
return max;
console.log(findMax(array)); // 6
// using reduce
acc = current;
return acc;
}, 0);
console.log(output); // 6
// acc is just a label which represent the accumulated value till now,
// so we can also label it as max in this case
max= current;
return max;
}, 0);
console.log(output); // 6
Tricky MAP
const users = [
];
----------------------------------------------------------
// Get the count/report of how many unique people with unique age are there
// like: {29 : 2, 75 : 1, 50 : 1}
// We should use reduce, why? we want to deduce some information from the array.
Basically we want to get a single object as output
if(acc[curr.age]) {
acc[curr.age] = ++ acc[curr.age] ;
} else {
acc[curr.age] = 1;
}, {})
console.log(report) // {29 : 2, 75 : 1, 50 : 1}
Function Chaining
// First name of all people whose age is less than 30
const users = [
];
// function chaining
acc.push(curr.firstName)
return acc;
}, []);
To Be Continued ...