//Version A:
var let = true;
console.log(let);//true
//Version B:
let let = 0; //syntax Error: let is disallowed as a lexically bound name
console.log(let);
Is there any particular reason where we allow variable with name let
created using var
but not let
? With this experiment, is that also means that variable name let
is ok to exist on global level but not in some scope level? But isn't global is consider scope?
There is a list of reserved words, which cannot be used as variable names because they are used by the language itself. For example: let , class , return , and function are reserved.
let allows you to declare variables that are limited to the scope of a block statement, or expression on which it is used, unlike the var keyword, which declares a variable globally, or locally to an entire function regardless of block scope.
Once you've declared a variable with var or let , you can reassign a new value to the variable in your programming flow. It is possible if the variable is accessible to assign a value. But with const , you can't reassign a new value at all.
var declarations are globally scoped or function scoped while let and const are block scoped. var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared. They are all hoisted to the top of their scope.
const
and let
are recent additions to JS, but for a long time before they were added const
was a reserved keyword (presumably on the basis that it was thought to be a likely future addition to the language).
Since let
used to be a valid variable name, this is presumably for backwards compatibility.
Because the specification says so.
From https://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations-static-semantics-early-errors:
13.3.1 Let and Const Declarations
13.3.1.1 Static Semantics: Early Errors
LexicalDeclaration
:
LetOrConst BindingList;
- It is a Syntax Error if the BoundNames of BindingList contains
"let"
.
The variable statement specification has no such limitation, probably because let
was not in use at the time var
was defined, and changing the specification for var
would be a breaking change.
const
and let
have been introduced as Future Reserved Words in ECMA2011.
const
and let
as Future Reserved Words7.6.1.2 Future Reserved Words
The following words are used as keywords in proposed extensions and are therefore reserved to allow for the possibility of future adoption of those extensions.
FutureReservedWord ::
- class
- enum
- extends
- super
- const
- export
- import
The following tokens are also considered to be FutureReservedWords when they occur within strict mode code (see 10.1.1). The occurrence of any of these tokens within strict mode code in any context where the occurrence of a FutureReservedWord would produce an error must also produce an equivalent error:
- implements
- let
- private
- public
- yield
- interface
- package
- protected
- static
Later on in ECMA2012 both words were added as keywords, which may not be used as identifiers.
7.6.1.1 Keywords
The following tokens are ECMAScript keywords and may not be used as Identifiers in ECMAScript programs.
Keyword ::
- break
- delete
- import
- this
- case
- do
- in
- throw
- catch
- else
- instanceof
- try
- class
- export
- let
- typeof
- continue
- finally
- new
- var
- const
- for
- return
- void
- debugger
- function
- super
- while
- default
- if
- switch
- with
Whereas const
used as identifier is throwing errors in every mode, let
only throws an error while being in strict mode, which is still the case nowadays using your example:
Using let
as identifier without strict mode.
(function(){
//REM: Works
var let = 5;
console.log(let);
})();
Using const
as identifier without strict mode.
(function(){
//REM: Throws an error
var const = 5;
console.log(const);
})();
Using either let
or const
as identifiers in strict mode.
(function(){
'use strict';
//REM: Throws an error
var let = 5;
console.log(let);
})();
(function(){
'use strict';
//REM: Throws an error
var const = 5;
console.log(const);
})();
So historically ECMA was more strict with the keyword const
than let
from the get go. While let
may not be used as Identifier since ECMA2012, I assume it was overlooked due to backwards compatibility.
Here is the latest specification of let
and const
.
It's due to backwards compatibility, as you guessed. const
has always been a reserved word (called a FutureReservedWord
in the ES5 spec). You've never been able to name a variable const
, since the beginning of JavaScript.
let
had also been considered to be a FutureReservedWord
, but only in strict mode - but strict mode was only introduced with ES5, when ES6 was on the distant horizon.
'use strict';
let = 10; // errors
var
has always existed, so naming a variable var
has always been forbidden.
Variables have never been able to be named const
, but there was no such restriction with let
. If it had been made forbidden in (non-strict) ES5 or ES6, it would have broken backwards compatibility, which web standards strive not to break at all costs.
If, back when JS was first engineered, people had the foresight to think: "Maybe, in the future, we'll want to use the words const
and let
to declare variables, so we'll make them reserved keywords for now." Then you wouldn't see the inconsistency, because both would have been reserved from the beginning.
There are a number of similar keywords that sometimes have a special meaning in modern JS, but don't throw errors when used as variable names.
static = 5;
async = 10;
await = 15;
yield = 20;
console.log('finished without errors');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With