I'm reading Kyle Simpson: ES6 & Beyond and I am at the second chapter. In the section titled "Block-Scoped Functions" an example is given:
{
    foo();                  // works!
    function foo() {
        console.log("works!");
    }
}
foo();                      // ReferenceError
(the console.log was added by me for testability.)
I would expect this code to run foo successfully at the first call, even though the function is defined below the call and to crash at the second call due to ReferenceError, as the book is claiming. However, if I run this in Chromium (Version 71.0.3578.98 (Official Build) snap (64-bit)) both function calls are successfully executed and "works!" is outputted twice to the console. If I run the same script in FireFox, then the first function call does not log anything and the second function call, outside the scope is outputting "works!". So, Chromium and FireFox behave differently from each-other and from the expectations drawn from the book. I have transpiled this in babeljs.io and the result was:
"use strict";
{
    // works!
    var _foo = function _foo() {
        console.log("works!");
    };
    _foo();
}
foo(); // ReferenceError
Strangely, foo is defined as function scope, (the keyword var is used instead of the keyword let or const), so it is reachable from outside the scope, yet the call outside the scope was not changed to _foo, hence we will have an error, but if we change the script to
{
    foo();                  // works!
    function foo() {
        console.log("works!");
    }
}
window["foo"]();                        // ReferenceError
the transpiler does not change the name of foo to _foo. With all these experiments I have reached to the conclusion that if I intend to have a block-scoped function, I need to define it explicitly, like:
{
    foo();                  // works!
    let foo = function() {
        console.log("works!");
    };
}
foo();                      // ReferenceError
but then even the first call for foo crashes due to temporal dead zone issue. So, my question is: Why does a block-scoped function work outside the scope?
 
    