Scopes and Closures

Scopes and Closures

In JavaScript scope and closure are two fundamental concepts, scope determines the accessibility of variables, while closures are functions that keep certain variables safe and accessible even after their original functions have finished running.

Scope

In JavaScript, scope defines where variables can be accessed or referenced. While some variables can be accessed from anywhere within a program, and some variables may only be available in a specific block of code.

Types of Scope:

Global Scope

Variables declared outside of any function with var, let and const keyword are in Global Scope. Those variables can be accessed from any part of the code, including within any functions.

Example:

const flower = 'Rose';

function favouriteFlower(){
  return flower + ' is my favourite flower'
};
console.log(favouriteFlower());  //output:Rose is my favourite flower

In above code, variable flower is declared outside of the function, and we have accessed it within the function.

Local Scope

Variables declared inside a function with 'var' keyword are in local scope, also known as function scope. Those variables are only accessible within the function.

Example:

function favouriteFlower(){
  var flower = 'Rose';
  return flower + ' is my favourite flower'
};
console.log(favouriteFlower()); //Output: Rose is my favourite flower

console.log(`${flower} is my favourite flower`); //error:flower is not defined

In above code, variable flower is declared inside the function, thus we can access it within the function, but we we cannot access it outside the function, as it throws the error.

Block Scope

Variables declared with the 'let' and 'const' keywords have block scope. They are only accessible within the block of code in which they are declared.

Example:

{
  let flower = 'Rose';
  console.log(flower); //Prints Rose is my favourite flower
}
console.log(flower); //Error: flower is not defined

In example, variable is declared inside the block with let keyword, and we have accessed it within block, but it is not accessible outside the block.

Closure

Closure allows the inner function to remember the state of its parent function, even if the parent function has finished executing.

Creating Closure

Closures are created when an inner function refers to the variables from its outer function.

function greetingGenerator(greeting) {
  function greet(name) {
    console.log(greeting + ', ' + name + '!');
  }
  return greet;
}

var greetWithHello = greetingGenerator('Hello');
var greetWithGoodMorning = greetingGenerator('Good morning');

greetWithHello('Bob'); // Output: Hello, Bob!
greetWithGoodMorning('John'); // Output: Good morning, John!

In above example, greetingGenerator is a function which takes a greeting parameter. Inside greetingGenerator ,there's an inner function greet that has access to the greeting parameter. The outer function returns the inner function, which creates closure. This closure remembers the greeting value even after greetingGenerator has finished execution. Two closures (greetWithHello and greetWithGoodMorning) are created with different greetings. When the closures are called with different names, they use the remembered greetings to generate personalized greetings.

Read more