如何在ES6中检查一个`let`变量是否已经声明?

9
与传统的变量声明不同,传统的变量声明会附加到整个封闭函数范围,而不管它们出现在哪里。但是,let声明会附加到块级作用域,但是在块中出现之前不会初始化。

因此:

console.log( a ); // undefined
console.log( b ); // ReferenceError!

var a;
let b;

所以看起来这里没有应用提升。

问题

如果是这样,我该如何安全地检查变量是否已声明?

NB - 我所看到的选择是使用try/catch,并且当然始终将let变量放在作用域的最前面。但我的问题仍然存在。


1
你无法检查任何变量(无论是 let 还是 var)是否已声明。你只能检查它们是否已定义。不过,你为什么要这样做呢?你的使用场景是什么? - Aadit M Shah
3
我编辑了我的评论。你正在检查变量是否已定义,而不是检查它是否已声明。 - Aadit M Shah
1
当它试图使用 let 做一些不打算做的事情时,这真的算是学习吗?它是一个块级作用域,因此没有理由在该块之外检查它。 - GillesC
2
得有一个非常出色的代码块,才能在其中测试 let 变量。 - GillesC
假设您可以通过let测试变量是否已创建。如果它创建了或者没有,您要怎么办?没有使用try..catch或混乱使用delete是不可能判断一个变量是否已声明,仅当用于全局时才可行。对于本地变量,delete也无法正常工作。 - RobG
显示剩余2条评论
2个回答

9
似乎这里没有使用hoisting(变量提升)。 并不完全是这样。变量仍然覆盖了整个作用域,绑定是在进入作用域时创建的,就像使用“var”一样。 但是您是正确的,与“var”不同,它不会立即使用“undefined”初始化,只有在评估“let”语句时才会初始化。从作用域顶部到那里的区域称为“暂时性死区”-标识符已绑定,但是在使用时始终会抛出“ReferenceError”错误。
如何安全地检查变量是否已声明? 您不能,就像对于“var”一样。无论如何都不需要这个。

Bergi: 在我看来,使用 var 关键字可以通过 typeof 进行检查(除了变量值为 undefined 的情况,例如 var g=undefined),同时也可以通过 if ('x' in window) 进行检查(仅适用于全局作用域,而非局部作用域)。 - Royi Namir
@RoyiNamir:不确定您的意思,也不知道您的用例是什么。如果变量不存在或具有值“undefined”,typeof x始终返回“undefined”。无论它是否被声明。 - Bergi
你说:就像变量一样,你不能 — 我只是提到我可以通过 if ('a' in window) {..} 检查变量的 _存在_(但仅适用于全局范围)。 - Royi Namir
@RoyiNamir:我以为你是指可以使用 typeof 来实现这个。 - Bergi

5
那可能是与您想要的最接近的内容:

这是最符合您需求的:

try {
    console.log(typeof mima); // or any other use of variable
    let mima = 'no ni ma';
} catch (error) {
    console.log(error); // “Uncaught ReferenceError: mima is not defined(…)”

    // and then taking some actions regarding the situation
}

虽然它的有用性颇具争议。但如果我必须检查let变量,我会选择类似这样的方式。然而,请注意,您不能安全地使用let创建缺失的变量,因为它被catch块包围。但它不会破坏代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接