If you're a JS beginner, you must have heard these words.
Let's get in depth to understand more about these concepts in JS.
What is a Scope in JS?
A scope in JS is a context in which values and expressions are visible or can be referenced.
In simple words, Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime.
Types of scopes in JS:
JavaScript has 3 types of scopes :
- Global Scope : Any variable, function, expression that is present globally or not declared inside any other function belongs to the global scope. Variables, functions that declared in global scope can accessed from anywhere in the program.
var foo=23; // declared in the global scope
function greet(){
console.log(foo);
}
greet();// Prints '23'
console.log(foo)l //Prints '23'
- Local or Function Scope : Variables and functions that are enclosed in some other function become part of that function's local or function Scope. In other words, a local scope or function scope is associated with a function, when we declare variables and functions inside another function, they become part of the local/function scope and are restricted to that scope. Variables and function declared in function/local scope are accessible within that scope.
//Declared in Global Scope
var foo=23;
function bar(){
// Function or Local Scope
var message="Hello JavaScript"; // inside the local/function
scope of bar
console.log(message); // Prints 'Hello JavaScript'
console.log(foo); // Prints '23'
}
//Global Scope
console.log(message); // Uncaught ReferenceError: message is not
defined
- Block Scope : Variables declared with let and const can block scoped. That is, they can be enclosed within a pair of curly braces(blocks). Any variable/function declared with let or const, inside a pair of curly braces are only available within the scope of the braces. It stands true for only for variables that declared with let and const and not with var.
{ //Block scope
let message = 'Hello JavaScript'; // declared with let
var name = 'Debarshi'; // declared with var
console.log(message); // Prints 'Hello JavaScript'
}
//Global scope
console.log(name);// prints 'Debarshi'
console.log(message); // Uncaught ReferenceError: message is not
defined
Hoisting in JS:
In JavaScript, hoisting is a concept in which a function or a variable can be used before declaration.
Hoisting with variables and functions declared with var keyword.
Variables declared with var keyword gets hoisted to the top of the scope. If accessed before initialization they result undefined.
console.log(baz); // Prints 'undefined'
console.log(greet); // Prints 'undefined
greet(); // Prints 'TypeError: greet is not a function'
var baz="Hello World!";
//anonymous function stored in a variable
var greet=function(){
console.log("Hello JavaScript!");
}
greet(); // Prints 'Hello from JavaScript!'
Hoisting with variables and functions declared/assigned with let and const keyword
Although variables and functions declared/assigned to let and const are also hoisted, but they cannot be accessed until they have been initialized.
console.log(a); // Prints 'ReferenceError: Cannot access 'a'
before initialization'
console.log(name); // Prints 'ReferenceError: Cannot access 'm'
before initialization'
doSomething(); // Prints 'ReferenceError: Cannot access 'm' before
initialization'
let a = 45; // Initialized
const name="Debarshi"; // Initialized
const doSomething = function (){
console.log("Hello World!")
}
console.log(a) // Prints '45'
console.log(name) // Prints 'Debarshi'
doSomething(); // Prints 'Hello World!'
Hoisting with functions:
-
Functions declared with function keyword:
Functions that are declared with the function keyword
are also hoisted and can accessed from the top of the scope.
foo(); // Prints 'Hello from foo!' function foo(){ console.log("Hello from foo!"); }
-
Anonymous functions, functions expression:
As anonymous functions and function expressions are
assigned/stored to a variable, they behave same as
that of the variable depending on the variable type they
are assigned to.
baz(); // TypeError: baz is not a function foo(); // Uncaught ReferenceError: Cannot access 'foo' before initialization var baz=function(){ // assigned to var console.log("Hello from Baz"); } let foo=()=>{ assigned to let console.log("Hello from Foo"); } baz(); // Prints 'Hello from Baz' foo(); // Prints 'Hello from Foo'
Temporal Dead Zone in JS:
let and const variables cannot be read/written until they
have been fully initialized, which happens when they are
declared (if no initial value is specified on declaration,
the variable is initialized with a value of undefined).
Accessing the variable before the initialization results in
a ReferenceError.
{ // TDZ starts at beginning of scope
console.log(bar); // undefined
console.log(foo); // ReferenceError
var bar = 1;
let foo = 2; // End of TDZ (for foo)
}
Top comments (2)
This is actually not true, but is a convenient mental visualisation
Yup true. Many things go behind this. Added this, for easy understanding.