nu

nullとundefined の JavaScript

1個の演習

nullとundefinedについて

多くの他のプログラミング言語とは対照的に、JavaScriptには(意味のある)値が存在しないことを表す2つの異なるものがあります。 nullとundefinedです。

Null

プリミティブ値nullは、変数に対して意図的に「空の値」として使われます。 他の言語では、同様の仕組みが(存在しない)オブジェクトやポインター型にだけ使われることがあります。 JavaScriptでは、nullはあらゆる型に対して空の値を表すのが一般的です。

let name = null;
// name is intentionally set to "empty" because it is not
// available

変数がnullかどうかは、厳密等価演算子===を使って確認できます。 nullはプリミティブ値ですが、typeof演算子は歴史的な理由から「誤って」objectを返します。 つまり、これだけでは変数がnullかどうかを確認するのに使えません。

let name = null;

name === null;
// => true

// Pitfall:
typeof name;
// => 'object'

Undefined

値を代入されていない変数の型はundefinedです。1

つまり、nullが空の値(ただし値ではある)を表すのに対し、undefinedは値が完全に存在しないことを表します。🤯

undefinedはさまざまな場面で現れます。

  • 変数が値(初期化)なしで宣言されると、それはundefinedです。
  • オブジェクトに存在しないキーの値にアクセスしようとすると、undefinedになります。
  • 関数が値を返さない場合、結果はundefinedです。
  • 関数に引数が渡されない場合、その引数にデフォルト値がない限り、undefinedになります。
let name;
console.log(name);
// => undefined

let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined

function returnNothing() {
  return;
}
console.log(returnNothing());
// => undefined

変数がundefinedかどうかは、厳密等価演算子===またはtypeof演算子を使って確認できます。

let name;

name === undefined;
// => true

typeof name === 'undefined';
// => true

変数に手動でundefinedを代入することはおすすめしません。空の値を意図的に設定したことを明確にするために、代わりに常にnullを使いましょう。

オプショナルチェイニング

前述のとおり、JavaScriptでは、オブジェクトに存在しないキーにアクセスするとundefinedが返されます。 しかし、入れ子になった値を取得しようとして親のキーが存在しない場合、入れ子のキーの評価はundefinedに対して行われ、TypeError: Cannot read property ... of undefinedにつながります。 理論上は、入れ子のキーを取得しようとする前に、必ず親のキーが存在するかを確認する必要があります。 以前はよくAND演算子&&でこれを行っていましたが、深く入れ子になった値では、これは非常に長い式になってしまいます。

obj.level1 && obj.level1.level2 && obj.level1.level2.level3;

この問題を解決するために、オプショナルチェイニングが2020年に言語仕様に追加されました。 オプショナルチェイニング演算子?.を使うと、親がnullまたはundefinedでない場合にだけ、JavaScriptが入れ子のキーにアクセスしようとするようにできます。 それ以外の場合はundefinedが返されます。

const obj = {
  address: {
    street: 'Trincomalee Highway',
    city: 'Batticaloa',
  },
};

obj.residence;
// => undefined

obj.address.zipCode;
// => undefined

obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined

obj.residence?.street;
// => undefined

obj.residence?.street?.number;
// => undefined

Null合体

変数がnullまたはundefinedだった場合にデフォルト値を適用したい、という場面があります。 以前は、三項演算子?を使ったり、OR演算子||の遅延評価を利用したりして、これを行うことがよくありました。 これには、変数がnullまたはundefinedのときだけでなく、変数がfalsyである(例えば''や0)すべての場合にデフォルト値が適用されるという欠点があります。 これは簡単に予期しない結果を引き起こす可能性があります。

let amount = null;
amount = amount || 1;
// => 1

amount = 0;
amount = amount || 1;
// => 1

amount = 0;
amount ? amount : 1;
// => 1

これを解決するために、Null合体演算子??が導入されました。 オプショナルチェイニングと同様に、これは2020年に言語仕様に追加されました。 Null合体演算子??は、左辺のオペランドがnullまたはundefinedのときにだけ、右辺のオペランドを返します。 それ以外の場合は、左辺のオペランドが返されます。 これにより、デフォルト値をより正確に適用できるようになりました。

let amount = null;
amount = amount ?? 1;
// => 1

amount = 0;
amount = amount ?? 1;
// => 0

[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (2021年6月4日にアクセス)。

GitHubで編集 リンクは新しいウィンドウまたはタブで開きます

nullとundefinedを学習する