将 let 变量带出临时死区
Take let variable out of temporal dead zone
查看此代码:
<script>
let {foo} = null; // TypeError
</script>
<script>
// Here I want to assign some some value to foo
</script>
第一个脚本尝试通过解构赋值来声明 foo
。但是,null
无法解构,因此赋值会抛出 TypeError。
问题是 foo
变量被声明但未初始化,所以如果在第二个脚本中我试图引用 foo
,它会抛出:
foo = 123; // ReferenceError: can't access lexical declaration `foo' before initialization
并且let
变量不能重新声明:
let foo = 123; // SyntaxError: redeclaration of let foo
有没有办法把它从 TDZ 中取出来,以便我可以赋值并读取它们?
这是不可能的。临时死区和对未初始化 let
变量的访问受限预计是不可避免的。这是令人困惑和有问题的,但是预期的和预期的。
详情见spec:
NOTE let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.\
因此,如果变量未在声明时初始化(并且在初始化之前抛出显然会导致未初始化),则无法通过任何方式访问它。
但实际上,你的问题比throwing assigment更复杂。这是架构问题——你依赖于可变的全局变量。它很大 "no no no",您应该重构代码以使用显式依赖项。
查看此代码:
<script>
let {foo} = null; // TypeError
</script>
<script>
// Here I want to assign some some value to foo
</script>
第一个脚本尝试通过解构赋值来声明 foo
。但是,null
无法解构,因此赋值会抛出 TypeError。
问题是 foo
变量被声明但未初始化,所以如果在第二个脚本中我试图引用 foo
,它会抛出:
foo = 123; // ReferenceError: can't access lexical declaration `foo' before initialization
并且let
变量不能重新声明:
let foo = 123; // SyntaxError: redeclaration of let foo
有没有办法把它从 TDZ 中取出来,以便我可以赋值并读取它们?
这是不可能的。临时死区和对未初始化 let
变量的访问受限预计是不可避免的。这是令人困惑和有问题的,但是预期的和预期的。
详情见spec:
NOTE let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.\
因此,如果变量未在声明时初始化(并且在初始化之前抛出显然会导致未初始化),则无法通过任何方式访问它。
但实际上,你的问题比throwing assigment更复杂。这是架构问题——你依赖于可变的全局变量。它很大 "no no no",您应该重构代码以使用显式依赖项。