The let
statement cannot be used to avoid global variables in the way that you suggest. A top-level let
statement will still create variables in the global scope, it just won't create them as properties of the "global object" (typically window
).
<script>
'use strict';
let fromLet = 'from let';
var fromVar = 'from var';
</script>
<script>
console.log(fromLet); // 'from let'
console.log(fromVar); // 'from var'
console.log(window.fromLet); // undefined
console.log(window.fromVar); // 'from var'
</script>
This behaviour is primarily described in Section 8.1.1.4: Global Environment Records of the ECMAScript 6 specification. The gist of it is that there is a single global scope/namespace, but its values can be recorded in two different places. Global built-ins, function
declarations, var
declarations, and function*
(generator) declarations are recorded as properties of the global object, while everything else global (from let
, const
, class
, and other new constructs) is stored in an internal "environment record" which is not exposed as an object in the runtime.
Here are a few relevant excerpts to start from if you'd like to dig in to the details.
A global Environment Record is used to represent the outer most scope that is shared by all of the ECMAScript Script elements that are processed in a common Realm (8.2). A global Environment Record provides the bindings for built-in globals (clause 18), properties of the global object, and for all top-level declarations (13.2.8, 13.2.10) that occur within a Script.
Properties may be created directly on a global object. Hence, the object Environment Record component of a global Environment Record may contain both bindings created explicitly by FunctionDeclaration, GeneratorDeclaration, or VariableDeclaration declarations and binding created implicitly as properties of the global object. In order to identify which bindings were explicitly created using declarations, a global Environment Record maintains a list of the names bound using its CreateGlobalVarBindings and CreateGlobalFunctionBindings concrete methods.
Table 18 — Additional Fields of Global Environment Records
[[ObjectRecord]]
: Object Environment Record
Binding object is the global object. It contains global built-in bindings as well as FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings in global code for the associated Realm.
[[DeclarativeRecord]]
: Declarative Environment Record
Contains bindings for all declarations in global code for the associated Realm code except for FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings.
[[VarNames]]
: List of String
The string names bound by FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration declarations in global code for the associated Realm.
let
s a replacement for IIFEs and the encapsulation provided by a function's lexical scope?" then I think the answer would be a resounding no. The ES2015 replacement for global namespace objects and many current uses of IIFEs is modules.