【发布时间】:2018-11-11 20:48:39
【问题描述】:
我有一个内部函数,它引用了一个由其包含的外部函数初始化的变量:
function outer() {
function inner() {
if (foo) { ... }
}
let foo = 'bar';
inner(); // no error
};
但是,在某些情况下,可能会在执行定义foo 的语句之前调用内部函数。在这种情况下,任何对 foo 的引用都会在内部函数中导致 ReferenceError:
function outer() {
function inner() {
if (foo) { ... } // ReferenceError: foo is not defined
}
inner();
let foo = 'bar';
};
这让我感到惊讶,因为foo 具有块作用域,并且在执行内部函数时我位于封闭块内。
更令人惊讶的是,即使尝试使用 typeof 运算符检测这种情况(我一直认为这是测试未定义变量的安全方法)也会导致相同的 ReferenceError:
function outer() {
function inner() {
if (typeof foo !== 'undefined') { ... } // ReferenceError: foo is not defined
}
inner();
let foo = 'bar';
};
编辑:我现在明白这种行为是涉及let 和const 变量discussedelsewhere 的“时间死区”的结果。但是,我仍在寻找一种干净、安全的方法来处理这种情况。
是否有任何安全的方法来测试块范围的变量(例如,使用 'let' 或 'const' 创建的变量)是否已达到其声明?
【问题讨论】:
-
使用 this 关键字 => this.foo 来确定变量是否声明。
-
@NattamaiJawaharlalManikandan property
this.foo将与此范围内定义的 variable 完全不同。 -
"是否有任何安全的方法来测试块范围的变量是否已经初始化?" - 不,不是,除了
try/@987654334 @。但是你需要这个做什么?要么你想使用这个变量,要么你不想。如果由于您在初始化之前尝试访问它而引发错误,请不要解决它,而只需修复您的错误 - 在最后一行调用inner()。 -
@Bergi 在“真实”代码中需要这个的原因是因为 inner() 是一个错误处理函数,而 outer() 是一个请求处理函数。在 inner() (错误处理函数)中,我想收集由 outer() 收集的所有上下文信息,以便将其写入错误响应。
foo,在现实世界中,是一个将输入值解析为outer()的结果的变量,但在某些情况下,我们在foo被初始化之前就遇到了错误。因此,可能必须在 foo 初始化之前调用 inner()。 -
@MykWillis 你能举例说明你是如何检测错误的吗?是
try-catch吗?我不清楚inner和foo的确切范围是什么,它们不会嵌套在不同的块中吗?同样对于您所描述的内容,我建议您简单地使用var(或将let声明放在您的范围顶部)。
标签: javascript typeof