Search code examples
javascriptecmascript-5

Does let replace anonymous closures for having private variables?


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

Solution

  • 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.