Michi's Tech Blog

一人前のWebエンジニアを目指して

【JavaScript】条件によって変数の値を振り分ける

こんにちは!
スマレジ テックファームのMichiです!

今回はJavaScriptの基本的な内容ですが、意外と知らなかったので記事にします。

やりたいこと

変数の値を条件によって振り分けたい。
例えば、18歳以上か未満で料金設定が変わる場合の実装を考えてみます。

const age = 20;

if (age >= 18) {
  const price = 2000;
} else {
  const price = 1500;
}

console.log(price);

PythonPHPならこれで問題ないのですが、JavaScriptだと変数priceが定義されていないと怒られます。

Uncaught ReferenceError: price is not defined 

原因

const, 及びlet宣言はブロックスコープに対応した変数を宣言するため。
これらの変数は、宣言したブロックスコープ内でしか使用できない(書籍『JavaScript 本格入門』 p192より)。

要するに、ifブロックの中で宣言した変数はそのifブロックの中でしか使えないよ、という話です。

解決策

その① varを使う

varで宣言された変数はブロックスコープを持ちません。
なので、最初のコードのconstvarに変えるだけで解決します。

const age = 20;

if (age >= 18) {
  var price = 2000;
} else {
  var price = 1500;
}

いやいや、今どきvar使うのはいかんでしょ。理由は変数の巻き上げが起こるからです(詳しい解説はリンク先を参照)。
というわけでこの解決策はなし。

その② ifの外で最初に変数を宣言する

ifの中で変数宣言するとブロックスコープができてしまうなら、グローバルスコープで変数宣言すれがいいやん、という話です。

const age = 20;
let price;

if (age >= 18) {
  price = 2000;
} else {
  price = 1500;
}

当たり前だけど、最初にconstで宣言すると後から条件による値を再代入できなくなるから注意。
(そもそもconstで代入なしの宣言ってできないけど)

その③ 三項演算子を利用する

そもそもこのくらいの条件分岐なら三項演算子で書いちゃいなYO

const age = 20;
const price = age >= 18 ? 2000 : 1500

コードもすっきりしてて、可読性が高いですね!
実際に僕が実務で触ったコードはもっと複雑な分岐で三項演算子は使えませんでしたが、これくらいの分岐なら三項演算子一択な気がします。

まとめ

今回はJavaScriptの基本的なブロックスコープの仕組みについて解説しました。
JSもっと勉強せねばな~。