JavaScript は未定義を返します
JavaScript は、他のプログラミング言語よりもライブラリやフレームワークが少なくなっています。 null
と undefined
は、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
a
と b
、5
と 3
にそれぞれ値を割り当て、2つの引数を指定して関数を呼び出すと、これらの値を割り当てた後に出力として 15
が返されます。
次のコードは、return ステートメントの式を変更して、a
、b
、および 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
undefined
と null
の違い
JavaScript には、空の値を表す null
値と undefined
値の両方があります。
変数に明示的に割り当てられた値がない場合、JavaScript は未定義のプリミティブ値を変数に割り当てます。 名前が示すように、null は、他の割り当てられた値が意図的に存在しないことを表すプリミティブ値です。
typeof
演算子を使用すると、以下のように null と未定義の区別を確認できます。
typeof undefined;
typeof null;
undefined
object
全体として、null は欠落しているオブジェクトを示し、未定義は初期化されていない変数で使用される値です。
まとめ
この記事では、初期化されていない変数、存在しないプロパティ、範囲外のインデックス、および void 演算子と共に undefined の発生について説明します。
説明したことに加えて、いくつかのベスト プラクティスは、例と一緒に使用するときに適用できます。 それとは別に、null と定義済みの値の違いとその使用例を調べました。
初期化されていない変数とスパース配列の使用を減らすことで、undefined の発生を減らすことをお勧めします。
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.