HOWTO · JavaScript

JavaScript は未定義を返します

この記事では、未定義の返品の例と、適応できるいくつかのベスト プラクティスについて説明します。 また、JavaScript の 2つのプリミティブ型である null と undefined の違いについても説明しています。

このページの内容

JavaScript は、他のプログラミング言語よりもライブラリやフレームワークが少なくなっています。 nullundefined は、JavaScript で空の値を表します。

undefined とともに発生するエラーを減らすには、undefined を返す理由を明確に理解する必要があります。 JavaScript における undefined の概要を簡単に見てみましょう。

JavaScript の未定義

JavaScript の 6つのプリミティブ型のうち、undefined は値が未定義の特殊な型のプリミティブです。 undefined 型が持つ唯一の値は undefined です。

undefined はグローバル スコープの変数で、書き込みも設定もできないプロパティです。 ECMA 仕様によると、変数に値が割り当てられていない場合、値 undefined が返されます。

// uninitialized variable
let letters;
console.log(letters);

// non-existing array elements
let vowels = ['a', 'e'];
console.log(vowels[3]);

// non-existing object properties
let flower = {name: 'Rose'};
console.log(flower.color);

出力:

undefined
undefined
undefined

出力にあるように、初期化されていない変数、存在しない配列要素、またはオブジェクト プロパティにアクセスすると、値 undefined が返されます。 各コード チャンクを個別に実行すると、3つの undefined 出力が得られます。

JavaScript が undefined を返す状況と、undefined を返す問題を解決するためのベスト プラクティスを見てみましょう。

出力として undefined を返すシナリオ

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

値を初期化せずに変数を宣言すると、変数は未定義を返します。

コード:

let letters;
console.log(letters);

出力:

undefined

コード チャンクと同様に、宣言された変数 letters には値が割り当てられていません。 上記の出力でわかるように、変数の呼び出しで undefined が返されますが、変数に値を代入すると、以下の値が返されます。

コード:

let letters = 5;
console.log(letters);

出力:

5

存在しないプロパティへのアクセス

存在しないプロパティにアクセスした場合、エラーの代わりに undefined が返されます。 以下の例はそれをよく証明しています。

コード:

let flower = {name: 'Rose'};
console.log(flower.color);

出力:

undefined

ここで、オブジェクト プロパティ flower は、name として 1つのプロパティを持ちます。 しかし、アクセスするとき、そのオブジェクトの存在しないプロパティである color プロパティを呼び出しました。

出力に示されているように、値 undefined が出力として返されます。

ベスト プラクティスとして、プロパティにアクセスする前に、次の構文を使用してプロパティの可用性を確認できます。 次に、出力として undefined を返すことを取り除くことができます。

構文:

'propertyName' in objectName

コード:

let flower = {name: 'Rose'};

if ('color' in flower) {
  console.log(flower.color);
}

関数パラメーターの呼び出し

定義された数の引数ではなく、より少ない引数で関数を呼び出すと、すべての引数を渡さないため、undefined が返されます。 したがって、同じ数の引数で関数を呼び出す必要があります。

コード:

function multiply(a, b, c) {
  a;
  b;
  c;
  return a * b;
}
console.log(multiply(5, 3));

出力:

15

ab53 にそれぞれ値を割り当て、2つの引数を指定して関数を呼び出すと、これらの値を割り当てた後に出力として 15 が返されます。

次のコードは、return ステートメントの式を変更して、ab、および c を乗算した後、同じ関数を同じ 2つの値で呼び出します。

コード:

function multiply(a, b, c) {
  a;
  b;
  c;
  return a * b * c;
}
console.log(multiply(5, 3));

出力:

NaN

出力に示されているように、計算値の代わりに NaN を返します。 これが表示される理由は、すべての引数が渡されず、c の値が undefined のままであるためです。

関数の return ステートメント

出力が undefined として返される別のインスタンスは、関数に return ステートメントがないか、近くに式がない return ステートメントがある場合です。

たとえば、与えられた入力に従って平方数を生成する sq_num という名前の関数を宣言しましょう。

コード:

// doesn't have a return statement
function sq_num(x) {
  const result = x * x;
}
console.log(sq_num(2));

// return statement without an expression
function sq_num(x) {
  const result = x * x;
  return;
}
console.log(sq_num(2));

出力:

undefined
undefined

この関数 sq_num を期待どおりに動作させるには、return ステートメントと以下のコードで言及されている式を宣言する必要があります。 それにより、以下のように関数の計算結果を得ることができます。

コード:

function sq_num(x) {
  const result = x * x;
  return result;
}
console.log(sq_num(2));

出力:

4

配列内の境界外要素へのアクセス

配列内で定義されていない要素にアクセスすると、範囲外の要素にアクセスしていると見なすことができます。 このような状況が発生した場合、undefined 値が返されます。

コード:

const animals = ['elephant', 'tiger', 'monkey'];
console.log(animals[5]);
console.log(animals[-1]);

出力:

undefined
undefined

同様に、スパース配列でも同じ問題が発生します。 スパース配列は、ギャップとインデックスのない要素を持つ配列です。

配列の空のスロットにアクセスすると、未定義の値も返されます。

コード:

const SparseArray = ['elephant', , 'monkey'];
console.log(SparseArray);

出力:

["elephant", undefined, "monkey"]

ここでは、配列 SparseArray が 3つの要素で作成され、2 番目の要素が欠落しています。 以下に示すように、2 番目の要素にアクセスすると undefined が返されます。

コード:

const SparseArray = ['elephant', , 'monkey'];
console.log(SparseArray[1]);

出力:

undefined

上記のシナリオとは別に、値 undefined が void 演算子とともに返されます。 以下は、評価結果にもかかわらず undefined を返す例です。

コード:

void 2;
console.log(void (true));

出力:

undefined

undefinednull の違い

JavaScript には、空の値を表す null 値と undefined 値の両方があります。

変数に明示的に割り当てられた値がない場合、JavaScript は未定義のプリミティブ値を変数に割り当てます。 名前が示すように、null は、他の割り当てられた値が意図的に存在しないことを表すプリミティブ値です。

typeof 演算子を使用すると、以下のように null と未定義の区別を確認できます。

typeof undefined;
typeof null;
undefined
object

全体として、null は欠落しているオブジェクトを示し、未定義は初期化されていない変数で使用される値です。

まとめ

この記事では、初期化されていない変数、存在しないプロパティ、範囲外のインデックス、および void 演算子と共に undefined の発生について説明します。

説明したことに加えて、いくつかのベスト プラクティスは、例と一緒に使用するときに適用できます。 それとは別に、null と定義済みの値の違いとその使用例を調べました。

初期化されていない変数とスパース配列の使用を減らすことで、undefined の発生を減らすことをお勧めします。