2

If you want to have some kind of private variables in JavaScript you could place the code in an anonymous closure, right? Now since let was included, is this specific use case of a closure gone? Or is it still relevant?

Example in top level:

// global variable a
var a = 6;

// using let
{
  // new variable a that only lives inside this block
  let a = 5;
  console.log(a); // => 5
}

console.log(a); // => 6

// using a closure
(function() {
  // again a new variable a that only lives in this closure
  var a = 3;
  console.log(a); // => 3
})();

console.log(a); // => 6
SimonH
  • 1,385
  • 15
  • 35
  • 1
    what is the question ? – Kunal Mukherjee Apr 12 '19 at 11:28
  • @KunalMukherjee Since I have very few experience developing in JavaScript I wanted to know if using a closure for this use case is still the right choice, or if it's better to use `let` (apparently using let everywhere you can is the way to go - at least instead of var. That's what I learned from reading all the fancy blog posts about let.) – SimonH Apr 12 '19 at 11:33
  • 1
    those closure are called [IIFE](https://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript) and before ES6 2015 they were the only way to go if we were to use private variables without polluting the global scope. Now since `const` and `let` have arrived you should use them because they give [block scope](https://edgecoders.com/function-scopes-and-block-scopes-in-javascript-25bbd7f293d7?gi=26a2ac2feb07). But for code which stills needs to execute inline we use an [IIFE](https://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript). – Kunal Mukherjee Apr 12 '19 at 11:38
  • What do you mean with `code which stills needs to execute inline`? I understand that code inside an IIFE will be executed immediately, but won't be code inside a block will be executed immediately, too? – SimonH Apr 12 '19 at 11:46
  • 1
    say if you wanted to make an AJAX call to the server to get some data from the database on the page load or some pre-initialization regardless of any condition, in those cases you'd still need an IIFE to accomplish that – Kunal Mukherjee Apr 12 '19 at 11:50
  • So I would make the request and use an IIFE as the callback? Maybe you want to formulate your comments as an answer since you actually answered my question (and maybe provide a code snippet which underlines your example? That would be great as I didn't find that specific example in a quick google session). – SimonH Apr 12 '19 at 12:04

1 Answers1

2

There is something called Hoisting in Javascript, which "hoists" the variable above even before initialization.

// global variable a
var a = 6;

// using let
{
  // new variable a that only lives inside this block
  let a = 5;
  console.log(a); // => 5
}

console.log(a); // => 6

// using a closure
(function() {
  // again a new variable a that only lives in this closure
  var a = 3;
  console.log(a); // => 3
})();

console.log(a); // => 6

So this code changes to:

// The global variable 'a' is hoisted on the top of current scope which is Window as of now
var a;

// Initialization takes place as usual
a = 6;


// This is a block
{

  // This local variable 'a' is hoisted on the top of the current scope which is the 'block'
  let a;

  a = 5;
  console.log(a); // => 5
}

console.log(a); // => 6

// Using an IIFE
(function() {

  // This local variable 'a' is hoisted on the top of the current scope which is the block of IIFE
  var a;

  a = 3;
  console.log(a); // => 3
})();

console.log(a); // => 6

Pre ES6 we used to use IIFEs to make variables which would not pollute the global scope, but after ES6 we generally use let and const because they provide block-scope.

Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53