Reputation: 5042
Consider following code snippet:
<script>
let a = 1;
console.log(a); //prints 1
</script>
<script>
console.log(a); //prints 1
</script>
I want to ask if a
is block scoped due to the declaration by let
which means it is scoped to single <script>
tag the why a
in second script tag is printing value 1?
Upvotes: 4
Views: 84
Reputation: 11
A variable created with let
on global space is present in a separate scope called script scope, even if it's present in the script tag in HTML or an external JS file.
Upvotes: 1
Reputation: 1375
When code is running in script
tag it will use global scope. For global scope v8 creates one Environment Record
to which your a
identified is assigned. That's why different script
tags have the same a
value.
Why is that?
First, let and const identifiers (variables) are scoped to Environment Record, according to https://tc39.es/ecma262/#sec-let-and-const-declarations (14.3.1 Let and Const Declarations)
let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment. The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated.
Second, for all scripts ecmascript uses the same Global Environment Record, according to https://tc39.es/ecma262/#sec-environment-records (9.1.1 The Environment Record Type Hierarchy)
A Global Environment Record is used for Script global declarations. It does not have an outer environment; its [[OuterEnv]] is null. It may be prepopulated with identifier bindings and it includes an associated global object whose properties provide some of the global environment's identifier bindings. As ECMAScript code is executed, additional properties may be added to the global object and the initial properties may be modified.
So, 1+1=your let variables are defined in script tags are defined in the same Global Environment Record
Upvotes: 0
Reputation: 66781
If you want to restrict the scope of that a
variable to the first <script>
element, then wrap the content in a block statement:
<script>
{
let a=1;
console.log(a); //prints 1
}
</script>
<script>
console.log(a); //Uncaught ReferenceError: a is not defined
</script>
Upvotes: 2