Block scoping with let and const

@skip the bullshit @scroll to examples

Since JavaScript was created we have only one way to declare variable - with a var statement.

var huncode = 'Someone who writes fast and damn simple code';  

It vas several problems with var:

  • If run outside function statements it declares in global namespace (developers writes couple of petabytes of articles and comments of how to prevent this. It was the first question on my first job interview).
  • Recreates variable in current scope if it's already exists. Millions of dollars was spent to pay developers who lose an hour trying to figure out why value isn't one as expect.
  • ...there are more, but I'm too lazy to continue (ping me and I will finish the list for sure).

Examples

Closure inside loop

Before block scopes it was a real problem to keep value inside loop or setTimeout, and we have to use tricky solutions, like:

var closures = [];

for (var i = 0; i < 5; i++) {  
  closures[i] = (function(storedIndex) {
    return function () {
      console.log('Current value is', storedIndex);
    };
  }(i));
}

closures.forEach(function (closure) {  
  closure();
});

But now with ES201x we have nice solution of the problem for cool guys.

const closures = [];  
for (let i = 0; i < 5; i++) {  
  closures[i] = () => {
    console.log(`Current value is ${i}`);
  };
}

closures.forEach(closure => closure());  

Bonus: const and let with switch block.

If one will try to use const or let inside switch-case statement "Uncaught SyntaxError: Identifier has already been declared" would be raised.

const total = 1;  
switch(total) {  
  case 'No total':
    const message = 'Message for no total';
    console.log(message);
    break;
  case 1:
    const message = 'Message for total == 1';
    console.log(message);
    break;
}

It happens because "block scope" in JavaScript just means "inside curved braces".
And simply adding curved braces to case will solve the error:

const total = 1;  
switch(total) {  
  case 'No total': {
    const message = 'Message for no total';
    console.log(message);
    break;
  }
  case 1: {
    const message = 'Message for total == 1';
    console.log(message);
    break;
  }
}