Home Web Front-end JS Tutorial Demystifying Closures in JS

Demystifying Closures in JS

Sep 01, 2024 pm 09:13 PM

Demystifying Closures in JS

  • Needs to be mastered to understand the intricate details of the language.
  • Not created like we create an array or function.
  • A fn returning another fn which is stored inside the LHS variable.
const secureBooking = function(){
  let passengerCount = 0;
  return function(){
    passengerCount++;
    console.log(`${passengerCount} passengers`);
  }
}

const booker = secureBooking();

booker();
booker();
booker();
Copy after login
  • secureBooking fn is executed in global scope.
  • A new execution context will be created on the global execution context.
  • Every execution context(EC) has its own variable environment with all of its variables. 'let passengerCount = 0' is defined inside this EC. It can access all varibles of its parent scope.
  • A new fn is returned, and will be stored in booker.
  • The Global EC will also contain the booker variable.
  • Now secureBooking() will be removed from EC and is gone. The secureBooking EC environment is no longer active. But still the passengerCount variable is being accessed which was defined at the time of fn creation.
  • Still, inner fn will be able to access the passengerCount varible defined inside outer fn. This happens due to closure.
  • Closure makes the fn remember the varibles defined surrounding the birthplace of the fn or its EC.
  • booker is not a fn, located in global scope.
  • Now executing booker(); for the first time will create an EC on the call stack, with its own variables.
  • A fn has access to the variable environment of the execution context in which the fn was created i. secureBooking. Hence, booker will have access to variables defined in variable environment of secureBooking fn. This connection of fn's birthplace i.e of definition to its surrounding variable environment is called Closure even after the EC of secureBooking fn containing the fn has popped out of Call Stack.
  • Closure: Variable Environment attached to the fn, exactly as it was at the time and place the fn was created.
  • Scope chain is preserved through the closure, even though EC is gone the variable enviroment keeps living somehow in the Engine. Hence, we say booker fn is closed over parent fn including parent fn arguments which we don't have here.
  • Using closure, a fn does not lose connection to the variables defined surrounding its birthplace.
  • If variable is not in current scope, JS looks into closure even before looking up the scope chain. Suppose if there is a global variable, even then the variable defined in its closure is looked up first.
  • Closure has priority over scope chain.
  • After running the booker() for the first time, value of passengerCount is incremented, logged in console and then booker is popped off call stack.
  • Execution moves to next line, a new EC is created but the closure variable is still there. The existing value is incremented and the EC is popped out.
  • Again the third time this process repeats.

SUMMARY

  • Defn: A closure is closed-over variable environment of the EC in which a fn was created, even after that EC has gone.

  • Also, a closure gives a fn access to all the variables of its parent fn, even after that parent fn has returned. The fn keeps a reference to its outer scope, which preserves the scope chain throughout time.

  • A closure ensures that the fn doesn't lose connection to variables that existed at the time of fn's birth. Its like a backpack that a fn carries around wherever it goes. This backpack has all the variables that were present in the environment where the fn was created.

  • We don't have to create closures manually. Also, we can't even access closed-over variables explicitly. A closure is not a tangible JS object i.e we cannot reach to a closure and take variables from it. Its an internal property of a fn. To take a look at backpack, "console.dir(booker);"
    [[Scope]] will show you about the VE of this fn call.

  • [[]] means its an internal property, which we cannot access from our code.

  • We always don't need to return a fn from another fn to create a closure. In below example, variable 'f' wasn't even defined inside the fn also, as its in global scope. Its able to access the 'a' variable also even after g() has finished its EC. 'a' is inside the backpack of 'f' now.

let f;

const g = function(){
  const a = 23;
  f = function() {
    console.log(a*2); // 46
  };
};


const h = function(){
  const b = 777;
  f = function(){
    console.log(b*2); // 1554
  };
};

g();
f();
console.dir(f);

// f fn is reassigned using h fn. Hence, old closure value i.e 'a' will be replaced with new value 'b' which can be verified using console.dir().
h();
f();
console.dir(f);
Copy after login
  • setTimeout(callbackFnToBeCalled, Delay);
  • Closure variables have higher priority over scope chain.
// Boarding Passengers using Closures
const boardPassengers = function(n, wait){
  const perGroup = n / 3;

  setTimeout(function(){
    console.log(`We are now boarding all ${n} passengers`);
    console.log(`There are 3 groups, each with ${perGroup} passengers`)
  }, wait*1000);

  console.log(`Will start boarding in ${wait} seconds`);
}

boardPassengers(180, 3);
Copy after login

The above is the detailed content of Demystifying Closures in JS. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1268
29
C# Tutorial
1241
24
Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

JavaScript Engines: Comparing Implementations JavaScript Engines: Comparing Implementations Apr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Python vs. JavaScript: The Learning Curve and Ease of Use Python vs. JavaScript: The Learning Curve and Ease of Use Apr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

JavaScript: Exploring the Versatility of a Web Language JavaScript: Exploring the Versatility of a Web Language Apr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration) How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration) Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration) Building a Multi-Tenant SaaS Application with Next.js (Backend Integration) Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

From C/C   to JavaScript: How It All Works From C/C to JavaScript: How It All Works Apr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

See all articles