2017-04-11 44 views
2

在他articleletconst杰森Orendorff规定如下:什么时候不能确定let或const是否被初始化?

松脆性能细节:在大多数情况下,你可以告诉 声明是否已用完或不只是看代码,所以 每次访问变量时,JavaScript引擎实际上都不需要执行额外的检查 以确保它已被初始化为 。但是,在封闭内部,有时不清楚。在 这些情况下,JavaScript引擎将执行运行时检查。这意味着 let可能比var慢。

我决定尝试找到一个例子,在这个例子中,这是真实的,并被难倒了。

例如,让我们来看看下面的折磨的场景:

function doSomethingDumb(q) { 
    function crash() { ++x; } 
    q.fn = crash; 
    crash(); 
    let x; 
    return crash; 
} 

即使关闭是在函数结束返回时,可以保证return语句将不会执行,甚至尽管x被分配给q的成员(并因此可能逃到野外),因此x将永远不会被初始化,因此crash将始终崩溃。

在什么情况下不可能判断变量是否已经初始化?

+0

'crash()'甚至不会执行,当您尝试将'x'分配给'q.fn'时,它已经崩溃。 – Bergi

+0

这应该是q.fn =崩溃。感谢您的支持。 – JeremiahB

+0

顺便说一句,你可以链接文章与该报价? – Bergi

回答

3

只是把那到只有时满足的条件:

function example() { 
    if (Math.random() < 0.33) tryIt(); 
    const x = 5; 
    if (Math.random() < 0.5) tryIt(); 
    function tryIt() { 
     console.log(x); 
    } 
} 

在这个例子中,我选择了一个随机的,但它可能也依赖于函数的输入参数。一般来说,访问变量的语句是否会在初始化之前被执行 - 这是halting problem并不是静态可判定的。你可以编写一个复杂的分析器,在很多情况下可以确定这一点,但总是在分析器的复杂性和开销之间进行折衷。

+0

我不知道这是如何回答操作问题 –

+0

@BekimBacaj问题是“*这里是一个例子,它很清楚'x'是否被初始化或没有被访问;什么情况下不明确?*”并且我已经展示了一个不容易看到的例子,并且在任何情况下都无法确定。 – Bergi

0

不存在缓慢或快速句柄的情况,即:命名值,无论是const还是let。没有“无法确定”这样的事情是否被初始化。 此外,let/s不会被初始化 - 它们只是被赋值。而且由于它们的作用类似于'未声明的变量',它们将在运行时分配它们的值,并恰好在它们的声明处分配。

因此,如果发生停止错误只发生let声明上方一行。它将继续完全不宣布。你只需看代码即可知道它。

+0

你可能想看看[this](http:// stackoverflow。com/q/31219420/1048572)对于'let' /'const'的“声明”和“初始化”是什么意思。 – Bergi

+0

这就是我刚才指出的 –

+0

嗯,它们在所有imo上的表现都不像未声明的变量。是的,尽管解释器总是可以确定(测试)变量是否已经初始化,但我们正在讨论编译器优化,以确定这样的测试是否有必要。这是不可判定的。 – Bergi

相关问题