为啥我不能在这个简单的函数中访问这个变量?

Posted

技术标签:

【中文标题】为啥我不能在这个简单的函数中访问这个变量?【英文标题】:Why I cannot access this variable inside this simple function?为什么我不能在这个简单的函数中访问这个变量? 【发布时间】:2020-12-28 10:42:46 【问题描述】:

我是 javascript 新手,我不明白范围在以下代码中是如何工作的:

//Code n°1:

let num = 1;

function test()
    console.log(num);


test()       //As I expected I get in console "1"
//Code n°2:

let num = 1;

function test()
    let num = 2;
    console.log(num);


test()       //As I expected I get in console "2"

但问题来了:

//Code n°3:

let num = 1;

function test()
    console.log(num)
    let num = 2;
    console.log(num);


test()       //I expected to get in console "1" and then "2" but instead I get an error.

当我在浏览器中运行代码 n° 3 时,我收到此错误: 未捕获的 ReferenceError:无法在初始化之前访问词法声明 'num'

如果我查看代码 1 和 2,我想在运行代码 3 后,我会在控制台中输入数字 1,然后是数字 2。但这并没有发生。为什么?

非常感谢!

【问题讨论】:

我认为它被称为临时死区 - 我假设你知道 var 不会发生这种情况 - 我还假设你知道如何提升 var 声明 - 没有这样的提升 let (或const ) 我原以为错误是关于重新声明 num。相反,错误是关于在初始化之前访问num,如果不深入了解 JavaScript 的解释方式,这是没有意义的,我没有。 【参考方案1】:

当词法变量在初始化之前被访问时,会发生 JavaScript 异常“在初始化之前无法访问词法声明‘变量’”。这发生在任何块语句中,当 let 或 const 声明在定义之前被访问时。

【讨论】:

我无法在上面发表评论,但您需要删除导致重新声明的 let。这在 javascript 中是不允许的。代码 2 正在工作,因为变量的重新声明不会发生在函数内部。第一个实例在它之外,然后你在函数内部更改它的值,这很正常。【参考方案2】:

当“测试函数”被调用时,函数体被执行。当它到达'console.log(num)' 时,它开始在测试函数范围内搜索'num 变量声明'(或'num assignment'或'num reassignment)。所以它在下一行找到变量声明。搜索变量的优先级是:

    当前范围 关闭 作用域链

所以,当在当前作用域中找到变量声明时,搜索不会继续作用域链。 (它不会在全局范围内搜索 num 变量。)

我猜这是错误的原因,但由于我是 javaScript 的新手,我并不完全确定。

【讨论】:

【参考方案3】:

如果你初始化变量没有重新声明,它会正常工作,现在如果你重新声明变量,那么这个错误会发生在letvar,因为在同一个作用域中,它被前面的console.log()调用。 不建议你重新声明 let 变量,如果需要,不要在前面的语句中使用相同的,注意如果你注释了第一个 console.log() ,代码将再次工作,这恰好发生在此范围内的变量的生命周期内,在这种情况下,let

let num = 1;

function test()

    console.log(num)
    let num = 2;
    console.log(num);


test()

【讨论】:

【参考方案4】:

因为在 javascript 中用 var 声明的函数和变量被提升,移动到函数/词法块的顶部。

但是让关键字尊重词法流。它在声明它的地方固定变量。

console.log 尝试访问在流程中声明的变量。 因此,手动将您的 let 声明向上移动到 de console.log 之上或将其更改为 var let num = 2;让javascript引擎自动移动它。

var num = 1;

function test()
    let num = 2;
    console.log(num);


test() 

var num = 1;

function test()
    console.log(num)
    var num = 2;
    console.log(num);


test() 

或者,访问全局 var num,它被测试主体的声明所遮蔽,var 或 let,不管

var num = 1;

function test()
    console.log(num)
    //let num = 2;
    console.log(num);


test() 

【讨论】:

以上是关于为啥我不能在这个简单的函数中访问这个变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的函数不能访问它所在类的私有变量 INSIDE?

为啥 useEffect 不能在 return 语句中访问我的状态变量?

为啥枚举的构造函数不能访问静态字段?

为啥模块中的这个公共函数无法访问

为啥我应该在属性访问器中使用私有变量?

为啥在调用它的析构函数后我可以访问这个堆栈分配的对象? [复制]