为什么允许 'let' 作为变量名?
Why is 'let' allowed as a variable name?
我想知道是否有人可以指出我刚刚发现的一些奇怪行为。因此,我在节点 REPL 中工作,运行 代码在我将其粘贴到模块中之前,我打错了字(好吧,没有完全填写行)'let = 5'。我预计这会出错,但 REPL 接受了它,我可以看到带有表达式结果和 console.logs 的值。所以我开始修补。我知道在 REPL 中,没有 let/const/var 的变量被认为是全局变量,但我想知道的是,为什么 REPL 允许我们这样分配 let ?下面我列出了我尝试过的东西(仅在 REPL 中,没有在模块脚本中尝试过)。
let = 5; //works
var = 5; //SyntaxError: Unexpected token "="
const = 5; //SyntaxError: Unexpected token "="
let let = 5; //SyntaxError: let is disallowed as a lexically bound name
var let = 5; //works
const let = 5; //SyntaxError: let is disallowed as a lexically bound name
let var = 5; //SyntaxError: Unexpected token "var"
var var = 5; //SyntaxError: Unexpected token "var"
const var = 5; //SyntaxError: Unexpected token "var"
let const = 5; //SyntaxError: Unexpected token "const"
var const = 5; //SyntaxError: Unexpected token "const"
const const = 5; //SyntaxError: Unexpected token "const"
那么为什么 let = 5
和 var let = 5
在逻辑上(至少对我而言)有效,所有这些语句都应该是语法错误?
编辑补充一下,let
在赋值后对变量赋值还是一样的。例如
let = 5;
let test = {};
console.log(let,test)
有效,并显示 5 {}
const
和 let
是最近添加到 JS 中的,但是在 long 时间之前 const
是一个保留关键字(大概是基于它被认为是该语言未来可能的补充)。
因为let
曾经是一个有效的变量名,这大概是为了向后兼容。
const
和 let
已在 ECMA2011.
中作为 未来保留字 引入
ECMA2011 - 引入 const
和 let
作为未来保留字
7.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
ECMA2012 - 批准的关键字
稍后在 ECMA2012 中,这两个词都被添加为关键字,不能用作 标识符。
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
而用作 标识符的 const
在每种模式下都会抛出错误,而 let
仅在严格模式下抛出错误,这仍然是现在使用您的示例的情况:
有效
在没有严格模式的情况下使用 let
作为标识符。
(function(){
//REM: Works
var let = 5;
console.log(let);
})();
无效
在没有严格模式的情况下使用 const
作为标识符。
(function(){
//REM: Throws an error
var const = 5;
console.log(const);
})();
在严格模式下使用 let
或 const
作为标识符。
(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);
})();
所以从一开始,ECMA 就关键字 const
比 let
更严格。虽然自 ECMA2012 以来 let
可能不会用作 标识符 ,但我认为由于向后兼容性它被忽略了。
Here是let
和const
的最新规范。
我想知道是否有人可以指出我刚刚发现的一些奇怪行为。因此,我在节点 REPL 中工作,运行 代码在我将其粘贴到模块中之前,我打错了字(好吧,没有完全填写行)'let = 5'。我预计这会出错,但 REPL 接受了它,我可以看到带有表达式结果和 console.logs 的值。所以我开始修补。我知道在 REPL 中,没有 let/const/var 的变量被认为是全局变量,但我想知道的是,为什么 REPL 允许我们这样分配 let ?下面我列出了我尝试过的东西(仅在 REPL 中,没有在模块脚本中尝试过)。
let = 5; //works
var = 5; //SyntaxError: Unexpected token "="
const = 5; //SyntaxError: Unexpected token "="
let let = 5; //SyntaxError: let is disallowed as a lexically bound name
var let = 5; //works
const let = 5; //SyntaxError: let is disallowed as a lexically bound name
let var = 5; //SyntaxError: Unexpected token "var"
var var = 5; //SyntaxError: Unexpected token "var"
const var = 5; //SyntaxError: Unexpected token "var"
let const = 5; //SyntaxError: Unexpected token "const"
var const = 5; //SyntaxError: Unexpected token "const"
const const = 5; //SyntaxError: Unexpected token "const"
那么为什么 let = 5
和 var let = 5
在逻辑上(至少对我而言)有效,所有这些语句都应该是语法错误?
编辑补充一下,let
在赋值后对变量赋值还是一样的。例如
let = 5;
let test = {};
console.log(let,test)
有效,并显示 5 {}
const
和 let
是最近添加到 JS 中的,但是在 long 时间之前 const
是一个保留关键字(大概是基于它被认为是该语言未来可能的补充)。
因为let
曾经是一个有效的变量名,这大概是为了向后兼容。
const
和 let
已在 ECMA2011.
ECMA2011 - 引入 const
和 let
作为未来保留字
7.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
ECMA2012 - 批准的关键字
稍后在 ECMA2012 中,这两个词都被添加为关键字,不能用作 标识符。
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
而用作 标识符的 const
在每种模式下都会抛出错误,而 let
仅在严格模式下抛出错误,这仍然是现在使用您的示例的情况:
有效
在没有严格模式的情况下使用 let
作为标识符。
(function(){
//REM: Works
var let = 5;
console.log(let);
})();
无效
在没有严格模式的情况下使用 const
作为标识符。
(function(){
//REM: Throws an error
var const = 5;
console.log(const);
})();
在严格模式下使用 let
或 const
作为标识符。
(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);
})();
所以从一开始,ECMA 就关键字 const
比 let
更严格。虽然自 ECMA2012 以来 let
可能不会用作 标识符 ,但我认为由于向后兼容性它被忽略了。
Here是let
和const
的最新规范。