概要: このチュートリアルでは、JavaScriptのundefined
(未定義)とその効果的な処理方法について学びます。
JavaやC#などの他のプログラミング言語を扱ったことがある場合、これらの言語にはnull
値があることに気付くかもしれません。
JavaScriptにもnull
値があります。さらに、undefined
値もあります。そして、null
とundefined
の両方の値は、JavaScriptでは空の値を表します。
undefined(未定義)とは
undefined
は、JavaScriptのプリミティブ型です。つまり、undefined
は型です。そして、undefined
型は、undefined
という1つの値のみを持ちます。
JavaScriptは、以下の状況でundefined
値を使用します。
1) 初期化されていない変数へのアクセス
変数を宣言して値を初期化しないと、変数の値はundefined
になります。例えば
let counter;
console.log(counter); // undefined
Code language: JavaScript (javascript)
可能な限り常に変数を初期化することをお勧めします。この例では、counter
変数を次のようにゼロに初期化できます。
let counter = 0;
console.log(counter); // 0
Code language: JavaScript (javascript)
2) オブジェクトの既存しないプロパティへのアクセス
既存しないオブジェクトのプロパティにアクセスすると、undefined
が返されます。例えば
let counter = {
current: 0
};
console.log(counter.max); // undefined
Code language: JavaScript (javascript)
この例では、counter
オブジェクトにはcurrent
というプロパティが1つあります。counter
オブジェクトに存在しないmax
プロパティにアクセスすると、undefined
が返されます。
プロパティにアクセスする前に、プロパティが存在するかどうかを確認することをお勧めします。JavaScriptには、そのための方法がいくつか用意されています。
そして、オブジェクトにプロパティが存在するかどうかを確認する最も一般的な方法は、in
演算子を使用することです。
'propertyName' in objectName
Code language: JavaScript (javascript)
オブジェクトのプロパティ名は、一重引用符または二重引用符で囲む必要があることに注意してください。
次の例では、in
演算子を使用して、max
プロパティがcounter
オブジェクトに存在するかどうかをアクセスする前に確認しています。
let counter = {
current: 0
};
if('max' in counter) {
console.log(counter.max);
}
Code language: JavaScript (javascript)
オブジェクトのプロパティが存在しない場合にデフォルト値を割り当てたい場合は、null合体演算子(??
)を使用できます。
const propValue = object.propName ?? defaultValue;
Code language: JavaScript (javascript)
この構文では、object.propName
がundefined
またはnull
の場合、null合体演算子(??
)はdefaultValue
を返します。
null合体演算子は、ECMAScript 2020から利用可能になっていることに注意してください。
let counter = { current: 0 };
const max = counter.max ?? 100;
Code language: JavaScript (javascript)
3) 関数パラメータ
関数を複数のパラメータで呼び出す場合、多くの場合、同じ数だけ引数を渡します。例えば
const formatCurrency = (amount, currency) => {
return currency === '$' ?
`$${amount}`: `${amount} ${currency}`;
}
Code language: JavaScript (javascript)
formatCurrency()
関数には2つのパラメータがあります。呼び出すときは、次のように2つの引数を渡すことができます。
formatCurrency(100,'$'); // $100
Code language: JavaScript (javascript)
そして、期待通り$100
が返されました。
しかし、formatCurrency()
関数を呼び出して、すべての引数を渡さない場合、関数内部のパラメータはundefined
になります。例えば
formatCurrency(100); // 100 undefined
Code language: JavaScript (javascript)
この状況を回避するために、次のように関数パラメータにデフォルト値を設定できます。
const formatCurrency = (amount, currency = '$') => {
return currency === '$' ?
`$${amount}`: `${amount} ${currency}`;
}
Code language: JavaScript (javascript)
そして、2番目の引数を渡さずに呼び出すと、適切な値が得られます。
formatCurrency(100); // $100
Code language: JavaScript (javascript)
4) 関数は値を返す
return
文のない関数は、暗黙的にundefined
を返します。例えば
const log = (message) => {
const time = (new Date()).toLocaleTimeString();
console.log(`${time}: ${message}`);
};
const result = log('Hi');
console.log(result); // undefined
Code language: JavaScript (javascript)
同様に、関数が式のないreturn
文を持つ場合も、undefined
を返します。例えば
const add = (a,b) => {
const result = a + b;
return;
}
let result = add(10,20);
console.log(result); // undefined
Code language: JavaScript (javascript)
次の例を考えてみましょう。
const add = (a,b) => {
return
a + b;
};
let result = add(10,20);
console.log(result); // undefined
Code language: JavaScript (javascript)
add()
関数はundefined
を返します。代わりに30を返す必要があります。
問題は、return
キーワードと戻り値の式(a + b
)の間に新しい行を作成すると、Javascriptコンパイラが自動的に新しい行の前にセミコロン(;)を挿入することです。この機能は、JavaScriptでは**自動セミコロン挿入(ASI)**と呼ばれています。
add()
関数は、JavaScriptコンパイラには次のように見えます。
const add = (a,b) => {
return;
a + b;
};
Code language: JavaScript (javascript)
そのため、戻り値としてundefined
が返されます。
5) 範囲外の配列要素へのアクセス
範囲外の配列要素にアクセスすると、undefined
値が返されます。例えば
const colors = ['red', 'green', 'blue'];
console.log(colors[3]); // undefined
Code language: JavaScript (javascript)
この例では、colors
配列にはインデックス3に要素がありません。したがって、colors[3]
はundefined
を返します。
まとめ
undefined
は、単一の値undefined
を持つプリミティブ型です。- 初期化されていない変数にアクセスすると、
undefined
が返されます。 - オブジェクトの既存しないプロパティにアクセスすると、
undefined
が返されます。 - 範囲外の配列要素にアクセスすると、
undefined
が返されます。 return
文のない関数、またはreturn
文はあるが式のない関数は、undefined
を返します。