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');
}