The let statement cannot be used to avoid global variables in the way that you suggest. The top-level let statement will continue to create variables in the global scope, it simply will not create them as properties of a "global object" (usually window ).
<script> 'use strict'; let fromLet = 'from let'; var fromVar = 'from var'; </script> <script> console.log(fromLet); </script>
This behavior is mainly described in Section 8.1.1.4: Global Environmental Reports of the ECMAScript 6 Specification . Its essence is that there is one global space / namespace, but its values ββcan be written in two different places. Global inline declarations, function declarations, var declarations and function* declarations (generator) are written as properties of a global object, and everything else global (from let , const , class , and other new constructions) is stored in an internal "environment record" that is not displayed as an object at runtime.
Here are some relevant passages to get you started if you want to delve into the details.
The global environment record is used to represent the external scope, which is shared by all ECMAScript Script elements that are processed in the general Realm ( 8.2 ). The Global Environment Record provides bindings for built-in global variables ( clause 18 ), global object properties, and for all top-level declarations ( 13.2.8 , 13.2.10 ) that occur inside Script.
Properties can be created directly on the global object. Therefore, the Environment Record object of the global environment record component can contain both bindings created explicitly using the FunctionDeclaration, GeneratorDeclaration or VariableDeclaration functions and bindings created implicitly as properties of the global object. To determine which bindings were explicitly created using declarations, the global Environment Record maintains a list of names associated with the specific CreateGlobalVarBindings and CreateGlobalFunctionBindings methods.
Table 18 - Additional Global Environment Data Fields
[[ObjectRecord]] : Recording the object environmentThe binding object is a global object. It contains global inline bindings, as well as FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings in the global code for the associated Realm .
[[DeclarativeRecord]] : Declarative environment recordContains bindings for all declarations in the global code for the corresponding Realm code, except for the FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings.
[[VarNames]] : List of stringsThe string names associated with the FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration declarations in the global code for the associated Realm .