如何安全地确定是否定义了块作用域变量
How to safely determine whether a block-scoped variable is defined
如果 const
或 let
变量的初始值设定项抛出错误,访问该变量会抛出 ReferenceError
-- 即使通过 typeof
.
// Foo.js
class Foo { constructor() { /* Something goes wrong and throws... */ } }
const gFoo = new Foo(); // Throws an error
// Elsewhere...
console.log(typeof gFoo); // throws ReferenceError: foo is not defined
是否有另一种方法来测试 gFoo
是否已成功初始化,或者我是否必须将 typeof
检查包装在 try
/catch
块中?
let isInitialized = false;
try {
if (typeof foo != 'undefined')
isInitialized = true;
} catch (e) {} // ugly but it works
主要是,我很惊讶typeof
can throw a ReferenceError。
当抛出错误时,当前函数停止执行(throw之后的语句将不会执行),控制权将传递给调用栈中的第一个catch块。那时,变量没有被初始化,导致 ReferenceError 异常。
因此,为了回答您的问题,只要您知道可能会抛出错误,请确保始终将其包装在 try catch 块中。
对于上述情况,由于错误可能发生在分配给 foo 的函数中,因此您应该在那里放置 try catch 块;类似于:
const foo = (() => {
try {
// Do whatever
throw Error();
// return value to assign to foo
} catch(err) {
// Log error for monitoring
// return undefined
}
})();
if (foo) {
// Do something with foo
} else {
// Do something if foo errored
}
如果 const
或 let
变量的初始值设定项抛出错误,访问该变量会抛出 ReferenceError
-- 即使通过 typeof
.
// Foo.js
class Foo { constructor() { /* Something goes wrong and throws... */ } }
const gFoo = new Foo(); // Throws an error
// Elsewhere...
console.log(typeof gFoo); // throws ReferenceError: foo is not defined
是否有另一种方法来测试 gFoo
是否已成功初始化,或者我是否必须将 typeof
检查包装在 try
/catch
块中?
let isInitialized = false;
try {
if (typeof foo != 'undefined')
isInitialized = true;
} catch (e) {} // ugly but it works
主要是,我很惊讶typeof
can throw a ReferenceError。
当抛出错误时,当前函数停止执行(throw之后的语句将不会执行),控制权将传递给调用栈中的第一个catch块。那时,变量没有被初始化,导致 ReferenceError 异常。
因此,为了回答您的问题,只要您知道可能会抛出错误,请确保始终将其包装在 try catch 块中。
对于上述情况,由于错误可能发生在分配给 foo 的函数中,因此您应该在那里放置 try catch 块;类似于:
const foo = (() => {
try {
// Do whatever
throw Error();
// return value to assign to foo
} catch(err) {
// Log error for monitoring
// return undefined
}
})();
if (foo) {
// Do something with foo
} else {
// Do something if foo errored
}