What I Wish Every Developer Knew About let In Javascript.

Written by mac | Published 2021/01/30
Tech Story Tags: javascript | let | es6 | tdz | block-scope | javascript-hoisting | hoisting | programming

TLDRvia the TL;DR App

One of the most widely used elements introduced in ES6 is the `let` variable initialization. Why is it better then `var`? Let's see.
The main similarity is that var and let allow you to initialize a variable without assigning a value. Afterwards, you can update and change that value.
let value;

value = 'string';

value = 1;

console.log(value);

// 1
And that's where the similarities end.

1. Block scope

function sayWhaaaat() {
    for(var i = 0; i < 4; i++) {
        var value = i;
    }
    console.log(value)
}

sayWhaaaat()

// 3
What's going on above? We declare using `var` a variable called value. And we can access it outside the block! If you try you will be able to console.log the `i` as well.
Initializing all variables using let will prevent similar issues as `let` is truly block scoped! When you replace the `var` with `let` and try to access it you will get `Uncaught ReferenceError: value is not defined`.
Why is it important?
  • you want variables to live only as long as it is required
  • did you expect `value` to be accessible? No? Exactly! Code should be predictable to avoid bugs.

2. No repeated declaration

function repeatedDeclaration() {
  var a = 'test'
  // some code
  var a = 'something else';
  return a;
}

repeatedDeclaration()
// 'something else'
The above is a massive simplification, but I have seen functions 800 lines long, so by accident you can overwrite a variable.
And if you do not write unit tests (Why writing unit tests is important) you might end up introducing a bug.
If you use `let` you would get `Uncaught SyntaxError: Identifier 'a' has already been declared` error.

3. TDZ - temporal dead zone

In ECMAScript 6, accessing a let or const variable before its declaration (within its scope) causes a ReferenceError. The time span when that happens, between the creation of a variable’s binding and its declaration, is called the temporal dead zone.

https://2ality.com/2015/10/why-tdz.html
Consider:
console.log(x); // a ReferenceError
let x = 'a string';
The above code throws a Reference Error. It is an improvement as it is likely a bug to use a variable before it is defined. See code using `var`:
console.log(y) // undefined
var y = 'another string'
Above we just get undefined, but is it helpful at all?
After seeing the above examples one may presume that TDZ is related to using a variable before it is defined. But it is not entirely the case.
Below example is from the book "JavaScript: The New Toys".
function temporalExample() {
    const f = () => {
        console.log(value);
    };
    let value = 42;
    f();
}
temporalExample();
If you run it, you will get 42 logged.
The `f` function even though references `value` doesn't use it until it gets called. The call happens after `value` is initialized.
So you still can use a value before it is declared. The problem is not related to where a variable is placed in the code, but when it is used.
Hope the above will help you writing better code and finally understand the most common use cases for using `let` instead of `const`. Enjoy!

Written by mac | During the day a developer. A husband and dad at night.
Published by HackerNoon on 2021/01/30