A global environment record consists of two parts
Environment records are conceptional data structures for storing the identifier name -> value
mappings.
As you might suspect, object environment records are backed by actual user space objects, such as the global object or an arbitrary object when you use with
. That's what makes global bindings become properties of the global object.
let
, const
and other declarations are store in the declarative environment record part which is backed by some implementation specific data structure. You have encountered declarative environments before because every function environment is a declarative environment. So one could also say "let
and const
are stored in the global scope the same way as any binding is stored in a function".
From the spec:
A global Environment Record is logically a single record but it is specified as a composite encapsulating an object Environment Record and a declarative Environment Record. The object Environment Record has as its base object the global object of the associated Realm. This global object is the value returned by the global Environment Record’s GetThisBinding concrete method. The object Environment Record component of a global Environment Record contains the bindings for all built-in globals (clause 18) and all bindings introduced by a FunctionDeclaration, GeneratorDeclaration, or VariableStatement contained in global code. The bindings for all other ECMAScript declarations in global code are contained in the declarative Environment Record component of the global Environment Record.