YovStudio

article 読むトレ #02:比較しているつもりですが…

公開日: 2025-06-21著者: Yov in YovStudio

今回のお題コード

まずは前回同様、AI にお題となるコードを提示してもらいましょう。

AI「ユーザーのテーマ設定で表示を分けるコードを書いてみました。どうでしょう?」

// 仮の関数(実際はデータベースなどから取ってくる想定)
function getUserSetting() {
  return {
    locale: 'ja-jp',
    theme: 'light'  // 'light' か 'dark'
  };
}

// ユーザー設定を読み込む
const userSetting = getUserSetting();

if (userSetting.theme = 'dark') {
  console.log("🌙 ダークモードを適用しました");
} else {
  console.log("🌞 ライトモードを適用しました");
}

どう動く?

さてみなさん、まずは自分でこのコードを読んでみて、どういう動きになるか予想してみましょう。

以下のようなサイトで動かしてみてもよいです。

気になる動き

実際に動かすと以下のような結果になります。

🌙 ダークモードを適用しました

あれ、ダークモードになっちゃいましたね?
たしかユーザー設定では themelight がセットされていたはずです。

function getUserSetting() {
  return {
    locale: 'ja-jp',
    theme: 'light'  // 'light' か 'dark'
  };
}

これならライトモードになるはずなのに、おかしいですね…

原因は「比較しているつもりが値の上書きをしているから」

このif文をよく見てみてください。

if (userSetting.theme = 'dark') {

= は比較ではなく代入を意味します。
つまり、userSetting.themedark で上書きします。さらにこの式は代入後に if ('dark') と評価され、JavaScript により「なんか true っぽいから true で!」とみなされてしまいます。これを truthy(トゥルーシー) と呼びます。逆に false っぽいものは falsy(フォルシー) と呼びます。

どう修正する?

ここでは比較をしたいはずなので、=== を使いましょう。 if ('light' === 'dark') と比較されることで条件式が if (false) と評価され、ライトモードの分岐に入ってくれます。

// '===' で比較する
if (userSetting.theme === 'dark') {

このように、比較のつもりが代入していたというケースは、実務でもたまに見かけます。
一見動いているように見えるので、しっかりパターンをテストしないと気づかれずに残りやすいです。

補足: ===== の違いは?

ほかの言語の知識がある方は、 「===?」「==じゃダメ?何が違うの?」と疑問に思ったのではないでしょうか。

JavaScript においても == は比較に使いますが、型の違いを無視するなど緩めの比較になります。
一方、===厳密な比較で、型も値も両方同じときだけ true になります。

'1' == 1     // true(文字列と数値が同じとみなされる)
'1' === 1    // false(型が違うのでダメ)

初心者のうちは、思わぬバグになるのを避けるためにも、基本的には === を使うのが安心です。

補足: truthy と falsy の例

truthy

以下はすべて true とみなされます。
= falsy でないものすべて

'hello'      // 文字列(空でなければ truthy)
123          // 数値(0 以外は truthy)
{}           // オブジェクト
[]           // 空の配列でも truthy
'false'      // 文字列としては中身があるので truthy(ややこしい!)

falsy

以下はすべて false とみなされます。

false
0
''           // 空文字
null
undefined
NaN          // 非数(数値計算の結果が数値で表現できない)

今回の読みどころ

  • if 文における ==== 、ちょっとした違いがバグの原因になる
  • 代入により意図せずユーザーデータを変えてしまう(場合によっては壊してしまう)ことがある
  • if 文で = が出てきたら本当に代入でいいの?と疑おう

おまけ:お題コードの修正版

// 仮の関数(実際はデータベースなどから取ってくる想定)
function getUserSetting() {
  return {
    locale: 'ja-jp',
    theme: 'light'  // 'light' か 'dark'
  };
}

// ユーザー設定を読み込む
const userSetting = getUserSetting();

if (userSetting.theme === 'dark') {
  console.log("🌙 ダークモードを適用しました");
} else {
  console.log("🌞 ライトモードを適用しました");
}