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