JavaScript undefined(未定義)

概要: このチュートリアルでは、JavaScriptのundefined(未定義)とその効果的な処理方法について学びます。

JavaやC#などの他のプログラミング言語を扱ったことがある場合、これらの言語にはnull値があることに気付くかもしれません。

JavaScriptにもnull値があります。さらに、undefined値もあります。そして、nullundefinedの両方の値は、JavaScriptでは空の値を表します。

undefined(未定義)とは

undefinedは、JavaScriptのプリミティブ型です。つまり、undefinedは型です。そして、undefined型は、undefinedという1つの値のみを持ちます。

JavaScriptは、以下の状況でundefined値を使用します。

1) 初期化されていない変数へのアクセス

変数を宣言して値を初期化しないと、変数の値はundefinedになります。例えば

let counter;
console.log(counter); // undefinedCode language: JavaScript (javascript)

可能な限り常に変数を初期化することをお勧めします。この例では、counter変数を次のようにゼロに初期化できます。

let counter = 0;
console.log(counter); // 0Code language: JavaScript (javascript)

2) オブジェクトの既存しないプロパティへのアクセス

既存しないオブジェクトのプロパティにアクセスすると、undefinedが返されます。例えば

let counter = {
   current: 0
};
console.log(counter.max); // undefinedCode language: JavaScript (javascript)

この例では、counterオブジェクトにはcurrentというプロパティが1つあります。counterオブジェクトに存在しないmaxプロパティにアクセスすると、undefinedが返されます。

プロパティにアクセスする前に、プロパティが存在するかどうかを確認することをお勧めします。JavaScriptには、そのための方法がいくつか用意されています。

そして、オブジェクトにプロパティが存在するかどうかを確認する最も一般的な方法は、in演算子を使用することです。

'propertyName' in objectNameCode 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.propNameundefinedまたは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,'$'); // $100Code language: JavaScript (javascript)

そして、期待通り$100が返されました。

しかし、formatCurrency()関数を呼び出して、すべての引数を渡さない場合、関数内部のパラメータはundefinedになります。例えば

formatCurrency(100); // 100 undefinedCode language: JavaScript (javascript)

この状況を回避するために、次のように関数パラメータにデフォルト値を設定できます。

const formatCurrency = (amount, currency = '$') => {
   return currency === '$' ?
     `$${amount}`: `${amount} ${currency}`;
}Code language: JavaScript (javascript)

そして、2番目の引数を渡さずに呼び出すと、適切な値が得られます。

formatCurrency(100); // $100Code 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); // undefinedCode language: JavaScript (javascript)

同様に、関数が式のないreturn文を持つ場合も、undefinedを返します。例えば

const add = (a,b) => {
    const result = a + b;
    return;
}

let result = add(10,20);
console.log(result);  // undefinedCode language: JavaScript (javascript)

次の例を考えてみましょう。

const add = (a,b) => {
    return 
       a + b;
};

let result = add(10,20);
console.log(result); // undefinedCode 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]); // undefinedCode language: JavaScript (javascript)

この例では、colors配列にはインデックス3に要素がありません。したがって、colors[3]undefinedを返します。

まとめ

  • undefinedは、単一の値undefinedを持つプリミティブ型です。
  • 初期化されていない変数にアクセスすると、undefinedが返されます。
  • オブジェクトの既存しないプロパティにアクセスすると、undefinedが返されます。
  • 範囲外の配列要素にアクセスすると、undefinedが返されます。
  • return文のない関数、またはreturn文はあるが式のない関数は、undefinedを返します。
このチュートリアルは役に立ちましたか?