【初心者向け】JavaScriptでundefinedを判定する正しい方法

JavaScriptでundefinedを正しく判定する方法を初心者向けに解説。typeof演算子、厳密等価演算子、void 0との比較など、安全で確実な判定方法を詳しく説明します。

Learning Next 運営
32 分で読めます

【初心者向け】JavaScriptでundefinedを判定する正しい方法

みなさん、JavaScriptでプログラムを書いていて、こんなことを思ったことはありませんか?

「この変数は値が設定されているかな?」 「undefinedかどうか、どうやって確認すればいいの?」

JavaScriptでプログラムを書いていると、変数がundefinedかどうかを判定することは、エラーを防ぐために非常に重要です。 しかし、間違った方法で判定するとバグの原因になることがあります。

でも大丈夫です!

この記事では、JavaScriptでundefinedを正しく判定する方法を初心者向けに詳しく解説します。 安全で確実な判定方法から、よくある間違いとその対処法まで、実用的なサンプルコードとともに説明していきます。

undefinedの判定をマスターして、安全なプログラムを作りましょう!

undefinedって、どんなときに発生するの?

undefinedが生まれる場面

undefinedは、JavaScriptで「値が定義されていない」ことを表す特別な値です。

以下のような場合に変数や値がundefinedになります。

// 宣言されているが値が代入されていない変数
let myVariable;
console.log(myVariable); // undefined
// 存在しないオブジェクトのプロパティ
const user = { name: '田中太郎' };
console.log(user.age); // undefined
// 存在しない配列の要素
const numbers = [1, 2, 3];
console.log(numbers[10]); // undefined
// 戻り値を返さない関数
function doSomething() {
// return文がない
}
console.log(doSomething()); // undefined

最初の例では、myVariableを宣言しただけで値を代入していないため、undefinedになります。

2番目の例では、userオブジェクトにageプロパティが存在しないため、アクセスするとundefinedが返されます。

3番目の例では、配列に存在しない10番目の要素にアクセスしているため、undefinedになります。

最後の例では、関数が値を返していないため、結果がundefinedになります。

このように、JavaScriptでは様々な場面でundefinedに遭遇します。

undefinedを判定する正しい方法

typeof演算子:最も安全で確実

最も安全で推奨される方法です。

// typeof演算子を使った判定(推奨)
function isUndefined(value) {
return typeof value === 'undefined';
}
// 使用例
let myVariable;
const user = { name: '田中太郎' };
console.log(isUndefined(myVariable)); // true
console.log(isUndefined(user.name)); // false
console.log(isUndefined(user.age)); // true
console.log(isUndefined(42)); // false
console.log(isUndefined('')); // false
console.log(isUndefined(null)); // false

この方法の最大の特徴は、どんな値でも安全にチェックできることです。

typeof演算子は、値の型を文字列で返します。 undefinedの場合は「'undefined'」という文字列が返されます。

この方法なら、変数が宣言されていなくてもエラーになりません。

typeof演算子の利点をまとめると以下の通りです。

  • 変数が宣言されていなくてもエラーにならない
  • undefinedが再定義されていても正しく動作する
  • 最も安全で信頼できる方法

厳密等価演算子(===):シンプルな方法

もう一つの一般的な方法です。

// 厳密等価演算子を使った判定
function isUndefinedStrict(value) {
return value === undefined;
}
// 使用例
let myVariable;
console.log(isUndefinedStrict(myVariable)); // true
console.log(isUndefinedStrict(42)); // false
console.log(isUndefinedStrict(null)); // false
// 注意:宣言されていない変数は参照エラーになる
// console.log(isUndefinedStrict(notDeclared)); // ReferenceError

この方法は見た目がシンプルで理解しやすいです。

===は厳密等価演算子と呼ばれ、型と値の両方が同じかどうかをチェックします。 nullとは区別されるので、正確にundefinedだけを判定できます。

ただし、宣言されていない変数をチェックしようとするとエラーになるので注意が必要です。

void 0を使う方法:古典的なテクニック

古いJavaScriptコードでよく見られる方法です。

// void 0を使った判定(古い手法)
function isUndefinedVoid(value) {
return value === void 0;
}
// void 0は常にundefinedを返す
console.log(void 0); // undefined
console.log(void 0 === undefined); // true
// 使用例
let myVariable;
console.log(isUndefinedVoid(myVariable)); // true

void 0は常にundefinedを返す式です。 昔はundefinedが書き換え可能だったため、この方法が使われていました。

現在では、より読みやすいtypeof===を使うことをおすすめします。

実用的なundefined判定関数を作ってみよう

詳細情報も一緒に取得する関数

undefinedかどうかだけでなく、詳細な情報も一緒に取得できる関数をご紹介します。

// 包括的なundefined判定関数
function checkUndefined(value, propertyPath = '') {
const result = {
isUndefined: typeof value === 'undefined',
type: typeof value,
value: value,
path: propertyPath
};
// 詳細情報を追加
if (result.isUndefined) {
result.message = propertyPath
? `${propertyPath} は undefined です`
: '値は undefined です';
}
return result;
}

この関数は、undefined判定だけでなく、値の型や詳細なメッセージも返してくれます。

デバッグ時にとても便利で、何がundefinedなのかが一目でわかります。

// 使用例
let myVariable;
const user = {
name: '田中太郎',
profile: {
email: 'tanaka@example.com'
}
};
console.log(checkUndefined(myVariable, 'myVariable'));
// {
// isUndefined: true,
// type: 'undefined',
// value: undefined,
// path: 'myVariable',
// message: 'myVariable は undefined です'
// }
console.log(checkUndefined(user.name, 'user.name'));
// {
// isUndefined: false,
// type: 'string',
// value: '田中太郎',
// path: 'user.name'
// }

実際の結果を見ると、undefinedの場合はメッセージも含まれ、そうでない場合は値と型がわかります。

オブジェクトプロパティの安全なチェック

オブジェクトのプロパティを安全にチェックする関数をご紹介します。

// オブジェクトプロパティの安全な確認
function hasProperty(obj, property) {
if (typeof obj !== 'object' || obj === null) {
return {
exists: false,
reason: 'オブジェクトではありません',
value: undefined
};
}
const hasOwn = Object.prototype.hasOwnProperty.call(obj, property);
const value = obj[property];
const isUndefined = typeof value === 'undefined';
return {
exists: hasOwn,
isUndefined: isUndefined,
value: value,
type: typeof value
};
}

この関数では、まずオブジェクトかどうかをチェックし、次にプロパティの存在と値を調べます。

hasOwnPropertyを使って、プロパティが実際に存在するかを確認します。 値がundefinedの場合と、プロパティ自体が存在しない場合を区別できます。

// 使用例
const user = {
name: '田中太郎',
age: 30,
address: undefined // 明示的にundefinedが設定されている
};
console.log(hasProperty(user, 'name'));
// { exists: true, isUndefined: false, value: '田中太郎', type: 'string' }
console.log(hasProperty(user, 'email'));
// { exists: false, isUndefined: true, value: undefined, type: 'undefined' }
console.log(hasProperty(user, 'address'));
// { exists: true, isUndefined: true, value: undefined, type: 'undefined' }

emailはプロパティが存在しないのでundefined、addressはプロパティは存在するが値がundefinedです。

ネストしたプロパティの安全な取得

深くネストしたオブジェクトのプロパティを安全に取得する関数をご紹介します。

// ネストしたプロパティの安全な取得
function safeGet(obj, path, defaultValue = undefined) {
if (typeof obj !== 'object' || obj === null) {
return defaultValue;
}
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (typeof current !== 'object' || current === null) {
return defaultValue;
}
if (typeof current[key] === 'undefined') {
return defaultValue;
}
current = current[key];
}
return current;
}

この関数では、「user.profile.contact.email」のような文字列パスを使って、安全にプロパティにアクセスできます。

途中でundefinedやnullに遭遇した場合は、デフォルト値を返します。

// 使用例
const user = {
name: '田中太郎',
profile: {
contact: {
email: 'tanaka@example.com'
}
}
};
console.log(safeGet(user, 'name')); // '田中太郎'
console.log(safeGet(user, 'profile.contact.email')); // 'tanaka@example.com'
console.log(safeGet(user, 'profile.contact.phone')); // undefined
console.log(safeGet(user, 'profile.contact.phone', '未設定')); // '未設定'
console.log(safeGet(user, 'profile.social.twitter')); // undefined

存在するパスは正常に値を取得し、存在しないパスはデフォルト値を返します。

undefined、null、空文字列の違いを理解しよう

それぞれの違いを確認する

JavaScriptには似たような「空」の値がいくつかあります。

// 様々な「空」の値を判定する関数
function checkEmptyValues(value) {
return {
value: value,
isUndefined: typeof value === 'undefined',
isNull: value === null,
isEmptyString: value === '',
isNaN: Number.isNaN(value),
isFalsy: !value,
isEmpty: typeof value === 'undefined' || value === null || value === '',
type: typeof value
};
}

この関数では、様々な「空」の状態をまとめてチェックできます。

undefined、null、空文字列、NaN、falsy値、そして独自定義の「空」判定を行います。

// テストケース
const testValues = [
undefined,
null,
'',
0,
false,
NaN,
' ',
[],
{},
'hello'
];
testValues.forEach(value => {
console.log(`値: ${value}`, checkEmptyValues(value));
});

様々な値でテストして、それぞれがどのような判定結果になるかを確認できます。

より厳密な「空」判定

実用的な「空」判定関数をご紹介します。

// より厳密な「空」判定
function isEmpty(value) {
// undefined または null
if (typeof value === 'undefined' || value === null) {
return true;
}
// 空文字列
if (typeof value === 'string' && value.trim() === '') {
return true;
}
// 空配列
if (Array.isArray(value) && value.length === 0) {
return true;
}
// 空オブジェクト
if (typeof value === 'object' && Object.keys(value).length === 0) {
return true;
}
// NaN
if (Number.isNaN(value)) {
return true;
}
return false;
}

この関数では、実際のアプリケーションでよく必要になる「空」の判定を行います。

空白だけの文字列、空の配列、空のオブジェクトなども「空」として判定します。

// 使用例
console.log(isEmpty(undefined)); // true
console.log(isEmpty(null)); // true
console.log(isEmpty('')); // true
console.log(isEmpty(' ')); // true
console.log(isEmpty([])); // true
console.log(isEmpty({})); // true
console.log(isEmpty(NaN)); // true
console.log(isEmpty(0)); // false
console.log(isEmpty(false)); // false
console.log(isEmpty('hello')); // false

0falseは有効な値として扱われ、「空」ではないと判定されます。

よくある間違いを避けよう

危険な判定方法

初心者がよくやってしまう間違った判定方法をご紹介します。

// ❌ 間違った方法
function badUndefinedCheck(value) {
// == を使用(危険)
return value == undefined; // null も true になってしまう
}
// ❌ 宣言されていない変数の参照
function anotherBadCheck() {
// 宣言されていない変数を直接参照(ReferenceError)
if (notDeclaredVariable === undefined) {
console.log('undefined');
}
}
// ✅ 正しい方法
function goodUndefinedCheck(value) {
return typeof value === 'undefined';
}

最初の例では、==演算子を使っています。 これは型変換を行うため、nulltrueになってしまいます。

2番目の例では、宣言されていない変数を直接参照してエラーになってしまいます。

// テスト
console.log(badUndefinedCheck(null)); // true(間違った結果)
console.log(badUndefinedCheck(undefined)); // true
console.log(goodUndefinedCheck(null)); // false(正しい結果)
console.log(goodUndefinedCheck(undefined)); // true

正しい方法を使うことで、undefinedとnullを正確に区別できます。

オブジェクトプロパティの間違ったチェック

オブジェクトのプロパティをチェックする際の間違いもよくあります。

const user = {
name: '田中太郎',
age: undefined // 明示的にundefinedが設定
};
// ❌ 間違った方法:in演算子だけを使用
if ('age' in user) {
console.log('ageプロパティは存在しますが、値はundefinedです');
}
// ❌ 間違った方法:hasOwnPropertyだけを使用
if (user.hasOwnProperty('age')) {
console.log('ageプロパティは存在しますが、値はundefinedです');
}
// ✅ 正しい方法:存在とundefinedの両方をチェック
function checkProperty(obj, prop) {
const hasProperty = Object.prototype.hasOwnProperty.call(obj, prop);
const value = obj[prop];
const isUndefined = typeof value === 'undefined';
return {
hasProperty,
isUndefined,
hasValidValue: hasProperty && !isUndefined
};
}

プロパティの存在と値の有無を分けて考えることが重要です。

プロパティがあってもundefinedの場合と、プロパティ自体がない場合は異なります。

console.log(checkProperty(user, 'name')); // { hasProperty: true, isUndefined: false, hasValidValue: true }
console.log(checkProperty(user, 'age')); // { hasProperty: true, isUndefined: true, hasValidValue: false }
console.log(checkProperty(user, 'email')); // { hasProperty: false, isUndefined: true, hasValidValue: false }

この結果から、nameは有効な値があり、ageはプロパティはあるが値がundefined、emailはプロパティ自体がないことがわかります。

実用的なundefined対策テクニック

デフォルト値を設定する方法

undefinedの場合に安全なデフォルト値を設定する方法をご紹介します。

// ES6のデフォルトパラメータ
function greet(name = '名無し', greeting = 'こんにちは') {
return `${greeting}${name}さん!`;
}
console.log(greet()); // こんにちは、名無しさん!
console.log(greet('田中太郎')); // こんにちは、田中太郎さん!

関数のパラメータでは、ES6のデフォルトパラメータが便利です。 引数がundefinedの場合に、自動的にデフォルト値が使われます。

// null合体演算子(??)を使用
function processValue(value) {
const processedValue = value ?? 'デフォルト値';
return processedValue;
}
console.log(processValue(undefined)); // デフォルト値
console.log(processValue(null)); // デフォルト値
console.log(processValue('')); // ''(空文字列はそのまま)
console.log(processValue(0)); // 0

null合体演算子(??)は、左側がnullまたはundefinedの場合のみ右側の値を使います。 論理OR演算子(||)と違って、空文字列や0は有効な値として扱われます。

// 論理OR演算子(||)との違い
function compareOperators(value) {
return {
nullishCoalescing: value ?? 'デフォルト',
logicalOr: value || 'デフォルト'
};
}
console.log(compareOperators(undefined)); // { nullishCoalescing: 'デフォルト', logicalOr: 'デフォルト' }
console.log(compareOperators('')); // { nullishCoalescing: '', logicalOr: 'デフォルト' }
console.log(compareOperators(0)); // { nullishCoalescing: 0, logicalOr: 'デフォルト' }

この違いを理解して、用途に応じて使い分けることが大切です。

オプショナルチェーニングで安全なアクセス

ES2020で導入されたオプショナルチェーニングを使った安全なプロパティアクセス方法をご紹介します。

// オプショナルチェーニング(?.)を使用
const user = {
name: '田中太郎',
profile: {
contact: {
email: 'tanaka@example.com'
}
}
};
// 従来の方法
function getEmailOld(user) {
if (user && user.profile && user.profile.contact && user.profile.contact.email) {
return user.profile.contact.email;
}
return undefined;
}
// オプショナルチェーニングを使用
function getEmailNew(user) {
return user?.profile?.contact?.email;
}
console.log(getEmailNew(user)); // 'tanaka@example.com'
console.log(getEmailNew(null)); // undefined
console.log(getEmailNew({})); // undefined

オプショナルチェーニング(?.)を使うと、途中でnullやundefinedがあっても安全にアクセスできます。 コードがとても短く、読みやすくなります。

// 配列でのオプショナルチェーニング
const users = [
{ name: '田中太郎' },
{ name: '佐藤花子' }
];
console.log(users?.[0]?.name); // '田中太郎'
console.log(users?.[10]?.name); // undefined
// メソッドでのオプショナルチェーニング
const api = {
getData: function() {
return 'データ';
}
};
console.log(api?.getData?.()); // 'データ'
console.log(api?.getUsers?.()); // undefined

配列やメソッドでもオプショナルチェーニングが使えます。

堅牢なバリデーション関数

実用的なバリデーション関数をご紹介します。

// 包括的なバリデーション関数
class ValueValidator {
static isDefined(value) {
return typeof value !== 'undefined';
}
static isNotNull(value) {
return value !== null;
}
static hasValue(value) {
return this.isDefined(value) && this.isNotNull(value);
}
static isValidString(value) {
return this.hasValue(value) && typeof value === 'string' && value.trim() !== '';
}
static isValidNumber(value) {
return this.hasValue(value) && typeof value === 'number' && !Number.isNaN(value);
}
static isValidArray(value) {
return this.hasValue(value) && Array.isArray(value) && value.length > 0;
}
static isValidObject(value) {
return this.hasValue(value) &&
typeof value === 'object' &&
!Array.isArray(value) &&
Object.keys(value).length > 0;
}
}

このクラスでは、様々な型のバリデーションメソッドを提供しています。 undefinedやnullのチェックから、より具体的な型チェックまで行えます。

// 使用例
console.log(ValueValidator.isDefined(undefined)); // false
console.log(ValueValidator.isNotNull(null)); // false
console.log(ValueValidator.hasValue('hello')); // true
console.log(ValueValidator.isValidString('')); // false
console.log(ValueValidator.isValidString('hello')); // true
console.log(ValueValidator.isValidArray([])); // false
console.log(ValueValidator.isValidArray([1, 2, 3])); // true

実際のアプリケーションでは、このようなバリデーション関数を組み合わせて使います。

まとめ:undefinedと上手に付き合おう

JavaScriptでundefinedを正しく判定する方法について、基本から実践的な応用まで詳しく解説しました。

重要なポイントをまとめると以下の通りです。

  • typeof value === 'undefined'が最も安全な判定方法
  • =====の違いを理解して適切に使い分ける
  • オプショナルチェーニング(?.)とnull合体演算子(??)を活用
  • 型安全な処理を心がける

実践での心がけ

undefinedを扱う際は、以下を意識しましょう。

  • 常にundefinedチェックを考慮した設計
  • デフォルト値の適切な設定
  • エラーハンドリングの実装
  • 堅牢なバリデーション関数の使用

undefinedは敵ではありません

適切に処理することで、より安全で予測可能なJavaScriptコードを書くことができます。 undefinedの特性を理解して、上手に付き合っていきましょう。

ぜひ今日から、これらの技術を活用してバグのない高品質なアプリケーションを作成してみてください! undefinedを恐れず、適切に対処できるプログラマーになりましょう。

関連記事