JavaScript のグローバル変数未定義エラーの回避方法

はじめに

JavaScript では、未定義のグローバル変数へのアクセスでエラーを出力します。ここでは、エラーを回避して、未定義を判定する方法を考えます。

失敗例

下記のコード例では、グローバル変数の未定義エラーで失敗します。

if (a) {
  console.log('OK');
} else {
  console.log('NG');
}
// Uncaught ReferenceError: a is not defined

//var a = undefined;
if (a !== undefined) {
  console.log('OK');
} else {
  console.log('NG');
}
// Uncaught ReferenceError: a is not defined

a = undefined;を事前に設定した場合、意図した動作となる。
 その場合、根本的に未定義ではなくなる。

回避策

window.property

if (window.a) {
  console.log('OK');
} else {
  console.log('NG');
}

グローバル変数に直接アクセスせずに、グローバル変数に間接的にアクセスします。

※変数が「undefined」「null」「false」「0」「""」の場合、誤判定する。
 完全ではないがほとんどの場合、「window.a」「!window.a」でこと足りる。
windowが存在しない環境の場合は、「window 以外のグローバル変数」を参照

in window

if ('a' in window) {
  console.log('OK');
} else {
  console.log('NG');
}

in演算子で指定したプロパティがオブジェクトに含まれるか判定します。

in 演算子 - JavaScript | MDN
windowが存在しない環境の場合は、「window 以外のグローバル変数」を参照

typeof

if (typeof(a) !== 'undefined') {
  console.log('OK');
} else {
  console.log('NG');
}

typeof演算子でオペランドの型名を判定します。

typeof - JavaScript | MDN
typeof(a) === void 0では動作しない。
 typeof(a)は、undefinedのプリミティブ値ではなく、文字列を出力する。

try/catch

try {
  a;
  console.log('OK');
} catch (e) {
  console.log('NG');
}

エラーが発生することを逆に利用して、 try/catch で捕獲します。

備考

window 以外のグローバル変数

上記の例でグローバル変数にwindowを使用しています。ですが、グローバル変数がwindowでないことがあります。windowを使用せずにグローバル変数を取得する方法は、次の通りです。

var global = globalThis;
var global = Function('return this')();

globalThis - JavaScript | MDN
※ Function を利用した方法は、最新環境で CSP 絡み制約を受けることがあります。

window 自身の有無を判定する

if ('window' in globalThis) {
  console.log('OK');
} else {
  console.log('NG');
}