Search code examples
ecmascript-6let

What is the actual advantage of using let/block scoping?


I can't seem to see the actual advantage of using let. Sure, if I have a for loop I would use let i = 0 instead of var i = 0 and i would now belong to the scope of the for loop block. But is that really advantageous? I mean I can use var and have the variable have function scope access but just not use it where I don't need to? What is the advantage to block scoping ?

I understand the difference between var and let, I want a more coherent understanding of let's particular advantages.


Solution

  • You already mentioned one advantage: Block scope in loops. This avoids issues with defining functions inside a loop, which I'd argue is one of the biggest pitfalls for people new to JavaScript:

    // With var
    var elements = document.querySelectorAll('.var');
    for (var i = 0; i < elements.length; i++) {
      elements[i].onclick = function() {
        console.log("I'm element #" + (i + 1) + ".");
      };
    }
    
    // With let
    elements = document.querySelectorAll('.let');
    for (let i = 0; i < elements.length; i++) {
      elements[i].onclick = function() {
        console.log("I'm element #" + (i + 1) + ".");
      };
    }
    <h3>With <code>var</code></h3>
    <div class="var">Click me!</div>
    <div class="var">Click me!</div>
    
    <h3>With <code>let</code></h3>
    <div class="let">Click me!</div>
    <div class="let">Click me!</div>

    Another advantage is that let variables aren't initialized by default. This makes it easier to catch mistakes when trying to access a variable with the same name in a higher scope:

    // With `var`, we get `undefined` which can be tricky to debug in more
    // complex code.
    var foo = 42;
    
    function bar() {
      console.log(foo); // undefined
      var foo = 21;
    }
    bar();

    // With `let`, we get a ReferenceError, which makes it clear that we made
    // a mistake here.
    var foo = 42;
    
    function bar() {
      console.log(foo); // ReferenceError
      let foo = 21;
    }
    bar();


    All in all this aligns JavaScript more with how other languages work.