2017-02-21 72 views
1

我想知道为什么我得到一个函数中的“x变量未定义”的错误,该函数使用一个变量,该变量是在执行功能。下面是摘录(ES6)函数,使用一个变量定义与让功能执行

let timeout = resetTimeout(); 

function resetTimeout() { timeout = 0; return timeout } 

为什么作用域作用吗?变量在函数定义之前被定义,所以,为什么?

编辑 为了澄清这个问题,我知道它可以与var。我已经阅读了关于let和const的范围,并且我无法理解为什么这不会像我期望的那样工作。我正在寻找的是解释,而不是解决方案。

+0

var'工作吗? – AshBringer

+0

当然var工作,关键是为什么它失败,让 – Danielo515

回答

2

您正在使用let创建一个变量,并立即为其分配函数的返回值。这没关系。

问题出在功能里面。没有指定变量timeout(= 0)的类型,你正在处理使用let之前定义的同一个超时。所以有一个循环引用。让我们来看看你的代码是如何执行的:

1 - 第一行调用该函数,timeout在该作用域中创建,但它的值尚未定义。

2 - 在函数体中,'timeout'被设置为0.由于它在范围内,所以js不能创建一个全局变量(通常会这样做)并且赋值会抛出一个错误。

修复?如果您希望功能块内的超时位于本地,只需重命名即可。

使用let就好了。

+0

谢谢你的回答。但是,我仍然不明白为什么函数没有看到外部范围中声明的变量。也许这与这个事实有关,即在表达式完成之前该变量不被认为是被声明的。由于该函数具有与变量声明的依赖关系,因此会创建某种依赖性循环,并且该表达式无法完成。然而,这是纯粹的猜测,我没有任何资料证实这一点,所以我在这里问了一些关于stackoverflow的信息。你知道我说的话是否有意义吗? – Danielo515

+0

它对我来说也有点奇怪。如果在函数块顶部声明变量,那么使用var或let不应该有任何区别。也许我们可以在这里看到更详细的解释。到目前为止,看起来你创建了一个有趣的悖论,揭示这种怪异,如果这种行为不是实施者所期望的。 –

+0

再次感谢你Bulent。你知道我能报告这种奇怪行为的地方吗? – Danielo515

-1

考虑到你的更新和这个家伙的回答,我想说明你不需要重命名你的变量。由于let只能在一个图层上工作,并且不会深入到范围中,因此可以在该函数内声明新的变量超时值。

let timeout = resetTimeout();

function resetTimeout(){let timeout = 0;返回超时; }

希望有所帮助。对不起,以前的答案。

+1

我知道它将与var。我已经阅读了关于范围界定的内容,而且我无法理解为什么这不能按我的预期工作。我正在寻找的是解释,而不是解决方案。 – Danielo515

+0

这不是真正的问题。 –

+0

@ Danielo515对不起,我当时不理解你。如果你想在函数内的本地函数内部超时,就像Bulent说的那样,你不需要重命名它,而不是timeout = 0;在函数中,写入let timeout = 0;希望能对你有所帮助。 –