Hoisting, strict mode and scope in javascript
Created on: Jul 26, 2024
JavaScript hoisting is a behavior in which variable and function declarations are moved to the top of their containing scope during the compilation phase. This means that no matter where variables and functions are declared, they are moved to the top of their scope before the code execution begins. However, only the declarations are hoisted, not the initializations.
In below code because x undefined because x is hoisted and in hoisting declaration comes to top not initialisation
console.log(x); // undefined var x = 5; console.log(x); // 5
In below code, we can run the code because fun is hoisted.
fun(); // "This function has been hoisted." function fun() { console.log("This function has been hoisted."); }
Variables declared with let and const are also hoisted, but they are not initialized. They are in a "temporal dead zone" from the start of the block until the declaration is encountered. Accessing the variable in this zone results in a ReferenceError.
console.log(y); // ReferenceError: Cannot access 'y' before initialization let y = 10; console.log(z); // ReferenceError: Cannot access 'z' before initialization const z = 20;
strict mode
Strict mode prevents the use of variables that are not declared. This means that if you try to use a variable before it is declared, strict mode will throw a ReferenceError
"use strict"; console.log(x); // ReferenceError: x is not defined
Scope
JavaScript variables have 3 types of scope:
- Function scope
- Global scope
- Block scope (with let and const)
- Lexical Scope (Closures)
var globalVar = "I am global"; function myFunction() { var functionVar = "I am local to this function"; console.log(functionVar); } // console.log(functionVar);// ReferenceError: functionVar is not defined, since function scope if (true) { let blockVar = "I am block scoped"; console.log(blockVar); // "I am block scoped" } // console.log(blockVar); // ReferenceError: blockVar is not defined
Lexical Scope
Closures are functions that retain access to their lexical scope even when the function is executed outside that scope.
function outerFunction() { var outerVar = "I am from outer function"; function innerFunction() { console.log(outerVar); // "I am from outer function" } return innerFunction; } const closure = outerFunction(); closure(); // "I am from outer function"