Javascript Fundamentals Flashcards
Execution Context
The process when a javascript starts running or a function is called, in order to allocate memory for variables and functions and then execute the code is called Execution Context
Call stack
Call stack is basically the order of execution or the order of executing different execution context so the JS engine can keep track of the which execution context belongs in which Code Execution.
As soon as a Execution context has finished executing and finished its work - it gets popped out of execution stack / call stack.
Memory Creation
The process of Execution Context has 2 phase. Memory Creation is the 1st phase in which all the variables are allocated space in memory with an undefined value. Functions are also allocated space and their value being the whole function itself.
This memory is called as Variable Environment.
Code Execution
This is the 2nd phase of Execution Context where all the code is executed and the previous undefined variables saved into memory is now given the respective value and expressions are evaluated.
When a function gets called during Code Execution, a new Execution stack is formed while the Execution stack has a new function popped over Global Execution Context to do the same action that Glocal Execution Context (GEC) goes through to evaluate the expressions.
Meaning Code Execution handle new Execution contexts inside the Global Execution Context.
This Code Execution takes place in a space known as Thread of Execution.
Hoisting
A phenomena in Javascript which allows us to access variables and functions even before they get declared in the function.
This is of course possible because of how JS engine works and the fact that when the Global Execution Context starts, it begins with allocating undefined to all variables and allocates the complete function into memory before any real execution starts, which makes it possible to access a variable even before we have declared a value for it.
Variable Environment
For every execution context, there are two parts - the memory creation phase, and the code execution phase.
During the memory creation phase, the js engine scans through the entire program to hoist all the variables into the memory and give them an undefined value (initially). This space where all the variables are stored forms the variable environment and this is the space that is passed onto the children functions/blocks as lexical environment.
Thread of Execution
The code execution phase of Execution Context occurs in a space called thread of execution.
Can you declare the same variable, say ‘x’, in the global execution context and then declare the same variable ‘x’ with a new value inside a function called inside GEC?
YES.
JS engine only looks at the local variable environment to use value from that environment, not outside. In case, it cant find the variable inside local environment - it starts to look in outside variable environment, usually Global Variable environment (obviously depends on what kind of program is being run though, it may be outside the local variable env, but it may still be inside Global Var Env)
So it is possible to have var x = 5 and then var x = 10 inside a function within the GEC.
Global Space
The space outside of any function where the memory has to be allocated and code is to be executed (still outside of any function) is Global Space. Global Space invokes the Global execution context.
What does ‘THIS’ keyword mean in a global space?
THIS keyword means the ‘window’ object in Global Space. ‘window’ object is responsible for holding all the variables written in a global space.
Scope and Scope Chain and Lexical Environment
Lexical Env is the local variable environment of a function plus the lexical environment of its parent.
Scope OF A VARIABLE defines where (or in which functions) can this declared variable be accessed.
A variable defined in the parent function can be accessed in the children functions.
Scope Chain is the chaining of these Lexical Environment and this also defines the scope of a variable.
Temporal Dead Zone, ‘let’ and ‘const’
let and const act differently than var
var is stored inside the window object, as we know. This allows it to be hoisted and accessed even before it is declared a value. Which is why we get undefined when trying to access it before declaration.
But let and const can get hoisted - but they are not stored within the ‘window’ object. They are stored in a separate instance and can not be accessed without having them declared.
The period in which the let and const variables get hoisted but cannot be accessed is known as temporal dead zone.
ReferenceError, SyntaxError, TypeError
ReferenceError is errors related to referencing. Such as trying to access an uninitialized variable, or trying to access undefined variable.
SyntaxError is errors relating to syntax and the JS engine just straight up nopes out even before executing a line of code in this case. Can happen when we try to initialize a constant (const) with a undefined value. Its not possible. Duplicate declaration of let variable also result in syntax error IN THE SAME EXECUTION CONTEXT. [duplicate declaration of var is possible]
TypeError is error usually related to typing. Like when we have initialized const variable to something and later on we try to assign another value - its not possible and it will return a TypeError.
Block Scope, Shadowing and Illegal Shadowing
Block is a collection of statements written between curly brace { }
Block scope follows the same lexical scope chain as in - a ‘let’ or ‘const’ variable declared inside a block cannot be accessed outside of the block. But a ‘var’ declared variable inside a block can also be accessed outside the block in the same execution context.
Where do you find blocks? After if-else statements within the curly braces { }. And after for/while loops within the curly braces { }.
Shadowing is a term used when we shadow a variable outside of a block (or of a function) with a new declared variable inside the block/function.
So say, we have declared var x outside the block - and then re-declare var x inside a block - it will be perfectly valid, and it will replace the value of ‘window.x’ to the new value. Because the scope of var is like that.
Whereas, if we declare a let ‘a’ value to something and then re-declare let ‘a’ to a new value, the new value of ‘a’ will remain inside the block - and as soon as we move out of the block, the value of ‘a’ will be switched to the OG declared value. The same happens for const.
Illegal Shadowing occurs when we try to re-declare a variable inside a block with a different type - say, outside we declare ‘let a’ and inside a block we re-declare ‘var a’. This will result in syntax error. Because scope of var is different from let. Redeclaring of variable works only if the scopes remain same. So a let and const redeclaration works but let and var doesnt nor does const and var.
Closures
The lexical environment of a function is called as closure. Closures can be visualized as the environment variable of the parent function along with its lexical environment. This whole thing form a closure.