ES6 Block Scoped Constants and Variables


Published: 2017-11-13
Updated: 2017-11-14
Web: http://fritzthecat-blog.blogspot.com/2017/11/es6-block-scoped-constants-and-variables.html


You may have asked yourself: "How can I recognize ES6 code quickly"? The most frequent difference to JS possibly is the occurrence of const constants and let variables. JS had var variables, and no constants. So if you see something like this ...

const yesWeCan = true;
// yesWeCan = false; /* causes error! */

... you know that it is an EcmaScript constant definition, the name of the constant being yesWeCan. A constant can be assigned a value just once, directly where it is defined. You can not change its value afterwards, like you can do it on variables.

let noICant = true;
noICant = false;

This was an EcmaScript variable definition, the name of the variable being noICant. Assigning another value causes no error.

{ Block Scope }

For Variables and Constants

The difference to JS var variables is that the ES6 let variables, and also const constants, are block-scoped.

{
    const iDontWant = false;
    let maybeICan = true;

    {
        alert(iDontWant);
        alert(maybeICan);
    }
}

alert(iDontWant); /* error, constant not known in this scope! */
alert(maybeICan); /* error, variable not known in this scope! */

This code opens a block (looks like an object declaration, but isn't). Inside the block, a variable and a constant are defined. Then another block opens, and they are used inside. So they are visible indefinitely inside nested blocks. Then both blocks are closed, and neither variable nor constant are visible any more. Both alerts would cause a runtime error.

So the ES6 block is actually the replacement for JS IIFE ("Immediately Invoked Function Expression"):

(function () {
    var jsVariableNotVisibleOutside = true;
})();

Mind that following JS code still would work, because JS variables are "hoisted" to the next enclosing function declaration, or to global scope when none exists:

{
    var jsVariableVisibleOutside = true;
}
alert(jsVariableVisibleOutside); /* not an error! */

What to learn here?

Don't use var any more when you write ES6 code, use const and let.
Prefer const, this will make your code really resistant (remember that functional languages do not allow variables!).

For Functions

Also functions are block-scoped in ES6.

{
    function foobar () {
        return 1;
    }

    if (foobar() !== 1)
        throw "Outer foobar failed!";

    {
        function foobar() {
            return 2
        }

        if (foobar() !== 2)
            throw "Inner foobar failed!";
    }

    if (foobar() !== 1)
        throw "Outer foobar was overwritten by inner!";
} 

This opens a block and defines a function foobar inside. It calls that function to asserts its return. Then it opens another block and again defines a function foobar there. This inner function "shadows" the outer one, as we can see on its return assertion. Then the inner block closes, and the outer foobar gets visible again.

Mind that the outer foobar would be available in the inner block if there wouldn't be another foobar!

Summary

ES6 comes closer to what is usual in programming languages than JS. Allowing to keep variables in block-scopes makes writing reusable code easier. Providing constants helps to avoid code corruption. The biggest difficulty for our eyes may become the similarity between object declarations and code blocks.





ɔ⃝ Fritz Ritzberger, 2017-11-13