如何安全地确定是否定义了块作用域变量

How to safely determine whether a block-scoped variable is defined

如果 constlet 变量的初始值设定项抛出错误,访问该变量会抛出 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
}