DEV Community

Kaziu
Kaziu

Posted on • Edited on

😇 "Javascript Closure" I think you can get what it is finally after reading this

💎 function in function

▼ in function can declare function in javascript

function outer(){ function inner(){ alert("poland"); } } outer(); // unfortunately, nothing happens 
Enter fullscreen mode Exit fullscreen mode

▼ we can write like this to execute inner function

function outer(){ function inner(){ alert("poland"); } inner() // here !!!!! } outer() // "poland" ! 
Enter fullscreen mode Exit fullscreen mode

💎 Anonymous function

now executing order is

  1. execute outer()
  2. declare inner()
  3. execute inner()

it's troublesome isn't it? 😅
yeah we can execute alert("poland") shorter by anonymous function

( function(){ alert("poland"); } )(); // "poland" 
Enter fullscreen mode Exit fullscreen mode

💎 function which return function

(in 2 min you can get what is closure finally)
▼ function can return function in Javascript

function outer(){ var inner = function (){ alert("poland"); }   return inner; } var func = outer(); func();// "poland"  
Enter fullscreen mode Exit fullscreen mode

▼ transform it a little bit, define inner function normally

function outer(){ function inner (){ //** here alert("poland"); }   return inner; } var func = outer(); func();// "poland" 
Enter fullscreen mode Exit fullscreen mode

▼ now delete inner() and use anonymous function

function outer(){ return function(){ //** here alert("poland"); } } var func = outer(); func();// "poland" 
Enter fullscreen mode Exit fullscreen mode

▼ then tranfrom a little bit, declare string "poland" before alert function

function outer(){ return function(){ var country = "poland" alert(country); } } var func = outer(); func();// "poland" 
Enter fullscreen mode Exit fullscreen mode

▼ -- ⭐ IMPORTANT!! -- At last move var country to outside inner anonymous function

function outer(){ var country = "poland" return function(){ /** ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ looks like we can't see country because country is declared outside anonymous function. But we can see it, this is typical closure ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ ⭐ **/ alert(country); } } var func = outer(); func();// "poland" console.log(country) // ⭐ undefined because of scope 
Enter fullscreen mode Exit fullscreen mode

▼ You can see easily with these eyes
Image description

💎 Real life example 1 (increment number)

there is typical question about closure

define function that return 1,2,3... each time you call it

it's not weird if you're asked about in in interview.

▼ If you write like this, result shows just 1 three times

function increment() { let num = 0 num = num + 1 } increment()//1 increment()//1 increment()//1 
Enter fullscreen mode Exit fullscreen mode

if we put let num = 0 in global variable

let num = 0 function increment() { num = num + 1 } increment()//1 increment()//2 increment()//3 
Enter fullscreen mode Exit fullscreen mode

the answer is correct, but someone could change this num so easily by chance, it's dangerous

function incrementFactory() { let num = 0 function increment() { num = num + 1 } return increment } // factory is just increment function const factory = incrementFactory() // ⭐ here only "increment()" execute, so it doesn't have effect to "let num = 0" factory()// 1 factory()// 2 factory()// 3 
Enter fullscreen mode Exit fullscreen mode

as you can see in that code, "num" can't call outside outer function, so we can create like private variable by closure

(▼just note for myself in Japanese)
incrementFactoryは最初の1回定義されるだけなので、let num = 0 が毎回定義されてnumが0になることはないっす

💎 Real life example 2

Honestly example 1 is hard to define "real life" example, even though it's important to know this knowledge.
But now I'm gonna show you more real life example.

this is typical jquery code

// anonymous function $('.button').click(function(){ alert('Hi!'); }); 
Enter fullscreen mode Exit fullscreen mode

then I can make function that prevent clicking more than 2 times

$(function(){ var isClicked = false; $('.button').click(function(){ if (isClicked) { alert('you have already clicked once !!'); return false; } isClicked = true; }); }); 
Enter fullscreen mode Exit fullscreen mode

Thank you for reading :)

ref:
https://qiita.com/takeharu/items/4975031faf6f7baf077a
http://dqn.sakusakutto.jp/2009/01/javascript.html

Top comments (1)

Collapse
 
peerreynders profile image
peerreynders
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" contents="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real world event listener accessing its closure</title> <style> main { max-width: 11ch; display: flex; flex-direction: column; align-items: stretch; } </style> <script type="module"> // `isClicked` is part of `clickListener`'s closure; let isClicked = false; const buttons = document.querySelectorAll('.button'); buttons[0].addEventListener('click', clickListener); buttons[1].addEventListener('click', simpleListener, { once: true }); // --- function clickListener(event) { // accessing/mutating `isClicked` in the "enclosing" closure if (!isClicked) { isClicked = true; event.target.textContent = 'Thank You!'; return; } alert(`That's quite alright, thank you!`); event.preventDefault(); event.stopPropagation(); } function simpleListener({ target }) { target.textContent = 'Thank You!'; target.disabled = true; } </script> </head> <body> <main> <button class="button">Click Me</button> <button class="button">Me Too!</button> </main> </body> </html> 
Enter fullscreen mode Exit fullscreen mode