function func(arg = 1) {
var arg = 2; // success
// let arg = 2; // SyntaxError: Identifier 'arg' has already been declared
}
我按照ECMA spec-7.0 FunctionDeclarationInstantiation算法查看为什么您可以使用var
重新声明函数体中的变量。
在步骤21中,已初始化所有参数。但算法都使用 CreateMutableBinding 来初始化var
(27.fi2)和let
(34.b.ii.1)体内声明的变量,为什么var
成功并let
失败了吗?我在算法中错过了哪些步骤?
答案 0 :(得分:1)
这就是所谓的"早期错误",这本质上是一个断言,规范声明应该抛出错误。在这种情况下,14.1.2 Static Semantics: Early Errors表示:
如果
BoundNames
的{{1}}的任何元素也出现在FormalParameters
的{{1}}中,则语法错误。
当您使用LexicallyDeclaredNames
或FunctionBody
时,您正在向let
的结果添加项目,这意味着它们将与函数参数中声明的变量冲突({{1} })。
使用const
不会出错,因为LexicallyDeclaredNames
不包含FormalParameters
语句。在此错误中包含var
s将是向后兼容性中断更改,因此它不会出错。