はじめに
フロントエンド開発をしていて、入力フォームやAPIのデータ構造を定義する際、こんな悩みに直面したことはありませんか?
「価格の初期値、null にすべきか undefined にすべきか……?」
「どちらも『空っぽ』だし、似たようなものじゃないの?」と思われがちですが、実は JavaScript / TypeScript の世界において、この両者には明確な役割の違いがあります。
この違いを正しく使い分けられないと、バックエンドとの連携時に「消したくないデータが消えてしまった!」といった予期せぬバグを招く原因にもなります。
今回は、それぞれの意味の違いから、通信時の挙動、そして「結局どちらを使うのがベストなのか?」なのかについて整理しました。
意味の違いを例えると?
| 値 | 状態 | 現実世界で例えると |
|---|---|---|
| null | 空(から) | 「値がない」ということを意図的に入れた状態。 |
| undefined | 未定義 | そもそも値が何なのか決まっていない(定義されていない)状態。 |
-
price: null
「この商品は無料です(価格 0 とは別)」とか「価格をあえて未設定にしました」という、開発者の明確な意図があります。 -
price: undefined
「価格のデータを入れ忘れた」「そもそも価格という概念を定義していない」など、まだ何も決まっていない状態です。
バックエンドに送られたときの挙動
ここが重要です!フロント(Angular)からバックエンド(Rails)にデータを送るとき、挙動が変わります。
-
null の場合
JSONに含めると{"price": null}となり、Rails側は「DBの price カラムを NULL(空)で更新しなさい」という命令として受け取ります。
// null の場合
JSON.stringify({ name: "T-shirt", price: null });
// 実行結果 -> '{"name":"T-shirt","price":null}' (nullが届く!)
-
undefined の場合
JavaScriptの標準的な挙動では、JSON.stringify を通すと、その項目自体が消滅します。 {"price": undefined} ではなく、{}(空っぽ)になります。 この場合、Rails側は「priceは送られてこなかったから、今の値を維持しよう」と判断することが多いです。
// undefined の場合
JSON.stringify({ name: "T-shirt", price: undefined });
// 実行結果 -> '{"name":"T-shirt"}' (priceが消える!)
結論
つまり、『今の値を壊したくない(更新したくない)』なら undefined を、『あえて空っぽに上書きしたい』なら null を選ぶのが、よいということになります。