2016-04-15 34 views
9

看到这个代码:就拿让变量out时间死区的

<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中取出,以便我可以分配值并读取它们?

+0

顺便说一句,我想使用'foo',而不是像'window.foo'这样的解决方法。 – Oriol

+0

我猜想有一件有趣的事情让第一个脚本确保初始化的有效性变得困难。 – Pointy

+0

@Oriol:'window.foo' [反正无法工作]:(http://stackoverflow.com/q/28776079/1048572):-) – Bergi

回答

2

这是不可能的。暂时死亡区域和限制访问未初始化的变量预计是不可避免的。这是令人困惑和有问题的,但意图和预期。

详见spec

注意让和const声明定义被限定在运行中的执行上下文的LexicalEnvironment变量。 变量在包含词法环境实例化时创建,但在以变量的LexicalBinding进行评估之前可能无法以任何方式访问。由LexicalBinding和初始化程序定义的变量在评估LexicalBinding时被分配其初始化程序的AssignmentExpression的值,而不是在创建变量时分配。如果在let声明中LexicalBinding没有一个初始化的变量赋值为未定义时LexicalBinding进行评估。\

所以,如果变量没有在声明中初始化(和初始化之前抛明显导致无初始化)它不能被任何方式访问。

但事实上,你的问题比投掷分配更复杂。这是架构问题 - 您依赖于可变全局变量。这很大“不,不”,你应该重构你的代码来使用显式依赖。