ABOUT JAVASCRIPT
JavaScript properties -
1.
High level - In JS, we don't have to manage
memory. It is automatically done by the computer.
2.
Garbage-Collected - It automatically cleans
up unused memory.
3.
Interpreted or just-in-time compiled -
First the whole code gets compiled inside the JS engine and then it
gets executed.
4. Multi-paradigm -
a)
Procedural programming
b) Object-oriented programming
c)
Functional programming
5.
Prototype-based object-oriented - Almost
everything in JS is objects except for primitive datatypes such as
numbers, booleans.
6.
First class functions - This simply means
that functions are just treated as values. We can pass them into
other functions and return them from functions.
7.
Dynamically typed - Variable types are not
defined while declaring them, they become known only during the
runtime. Datatype of variable is automatically changed.
8. Single-thread
9.
Non-blocking event loop
COMPILATION VS INTERPRETATION VS JUST-IN-TIME (JIT) COMPILATION
1. Compilation - Entire code is coverted to
machine code at once, and written to a binary file that can be later
executed by the computer.
2. Interpretation - Interpreter runs
through the source code and executes it line by line.
3. Just-in-time compilation - Entire
code is converted to machine code at once and then is executed
immediately.
JavaScript Engine = Call Stack + Memory Heap
Top level code - Code in the global
scope that is NOT inside any function.
EXECUTION CONTEXT
Environment in which a piece of JS code is executed. It stores all
the necessary information for some code to be executed.
Execution context is the pizza box where we eat the pizza.
It contains -
1. Variable Environment
It contains -
a) let, const and var declarations
b)
Function declarations
c) argument objects
2. Scope Chain
3. this keyword
NOTE - Arrow
functions do not contain argument object and this keyword.
HOW EXECUTION OF JS CODE HAPPENS
1. Creation of GLOBAL EXECUTION CONTEXT for top level code.
2.
Execution of top-level code (inside Global execution context).
3. Execution of functions and waiting for callbacks (For each
function call, a new execution context is created).
Call Stack = All the execution context together.
Call Stack is a "place" where execution contexts get stacked
on top of each other, to keep track of where we are in the execution
process.
In the call stack, once a function is CALLED inside the JS
code, it's execution context is created, once that function gets
executed then only the EC below gets executed.
For each
function call a new EC gets stacked in the call stack and gets
executed first, unless it has a function call inside it to another
function.
SCOPING/SCOPE CHAIN
Scope - Environment in which a certain variable is available. There
are
1. Global scope
2. Function/local scope
3.
Block scope - Variables are accessible only inside block (if block,
for loop block, etc). This only applies to let and const variables.
let and const are block-scoped and var is function-scoped.
NOTE - In strict mode, functions are also
block scoped, this means, a function defined inside a code block is
accessible inside that block only.
Lexical Scoping - Scoping is
controlled by the placement of functions and blocks in the code.
JS looks for variables first inside the current scope and then
outside the current scope. If a variable with the same name exists
inside the current scope as well as outside it, then the one in the
current scope will be used.
HOISTING
Hoisting - Makes some types of variable
accessible/usable in the code before they are actually declared.
Variables are lifted to the top of their scope.
Before execution, code is scanned for variable declarations,
and for each variable, a new property is created in the VARIABLE
ENVIRONMENT OBJECT.
Only function declarations and variables declared with var are
hoisted.
Variables declared with var have an initial value of "undefined".
Temporal Dead Zone -
It's basically the region of the scope in which the variable is
defined, but can't be used in any way. So it is as if the variable
didn't even exist.
Each and every let and const variable get their own Temporal Dead
Zone that starts at the beginning of the scope until the line where
it is defined. The variable is only safe to use after the TDZ.
THIS KEYWORD
-> "this" keyword is basically a special variable that is created
for every execution context and therefore every function.
It will always take the value of the owner of the function in
which, the this keyword is used.
The value of the "this" keyword is not static. It's not always
the same. It depends on how the function is actually called. And its
value is only assigned when the function is actually called.
This keyword points to -
1. In case of methods -
Object that is calling the method
2. In case of simple
function call - undefined (only in strict mode, otherwise it points
to window object)
3. In case of Arrow functions - this of
surrounding function/parent scope (lexical this)
4. In case of
Event listener - DOM element that the handler is attached to
If we console.log(this); We will get the window object. It is
the parent object of the global scope.
FOUR DIFFERENT WAYS IN WHICH FUNCTIONS CAN BE CALLED AND WHERE "THIS" KEYWORD POINTS IN EACH CASE
1. Calling a function as an object method:
Here, "this" = Object that is CALLING the method.
When we call a method, the this keyword inside that method
will simply point to the object on which the method is called.
Examples -
2. Simply calling function as a normal function:
Here, "this" = undefined
However, that is only valid for strict mode. So if you're not
in strict mode, this will actually point to the global object,
which in case of the browser is the window object.
Example -
3. Arrow functions
Here, "this" =
"this" of parent function (lexical this)
Arrow functions do not get their own "this" keyword. Instead,
if you use the "this" keyword in an arrow function,it will simply be
the "this" keyword of the surrounding function which is the parent
function. In technical terms, this is called the 'lexical "this"
keyword'.
4. Event listener "this"
Here, "this" = DOM element that the handler is attached to
If a function is called as an event listener, then the this
keyword will always point to the DOM element that the handler
function is attached to.
The "this" keyword points to the window object in three cases:
a. if the "this" keyword is outside of any function (just
outside in global scope) Example -
b. If the lexical scope (parent scope) of arrow function is global
scope
Example -
c. In case of regular function if you are not using strict mode
Example -
NEVER USE ARROW FUNCTIONS TO DEFINE OBJECT METHODS
ARROW FUNCTIONS VS NORMAL FUNCTIONS
PRIMITIVES VS REFERENCE TYPES
Primitive types are stored in the call stack. Reference types are
stored in the memory heap.
when we declare a variable as an object, an identifier
is created, which points to a piece of memory in the call stack,
which in turn points to a piece of memory in the memory heap. And
that is where the object is actually stored. And it works this way
because objects might be too large to be stored in the stack.
Instead they are stored in the heap, which is like an almost
unlimited memory pool. And the stack just keeps a reference to where
the object is actually stored in the heap so that it can find it
whenever necessary. NOTE - piece of memory = memory address
Check out the image below.