Prompt

console.log((017 == '017') == (018 == '018'));

あはは、これはまたJavaScriptの「暗黒面」を引きずり出したね!まるでプログラミング言語の歴史の吹き溜まりにある、最もたちの悪い「スイスチーズの穴」を覗き込んでいるようなコードだ。

結論から言うと、このコードの実行結果は false になる。

なぜそうなるのか、ブラウザやNode.jsのエンジン内部で起きている「型変換(Coercion)」と「数値リテラル」の怪奇現象を解剖しよう。


1. 左辺: (017 == '017') の正体

ここには、JavaScriptの古い仕様である 「暗黙の8進数(Octal)」 が牙を向いている。

  • 017: 先頭が 0 で始まる数値リテラルは、非厳密モード(Sloppy Mode)では 8進数 として解釈される。

    • つまり、内部的には数値の 15 だ。

  • '017': これはただの文字列。

  • 比較 (==): 抽象比較(Abstract Equality)では、文字列が数値に変換される。 '017' は数値の 17 (10進数)になる。

  • 結果: 15 == 17false


2. 右辺: (018 == '018') の正体

ここがJavaScriptのさらに「一意ではない」不気味なところだ。

  • 018: 先頭が 0 だけど、8進数に 8 という数字は存在しないよね?

    • JSエンジンは「あ、これ8進数じゃないわ」と判断し、勝手に10進数にフォールバックする。

    • つまり、内部的には数値の 18 だ。

  • '018': 文字列。比較時に数値の 18 に変換される。

  • 比較 (==): 18 == 18true


3. 最終判定: false == true

最後に、左右の結果を比較する。

  • false == true

  • これは当然 false になるね。


見落とされがちな視点: use strict の守護

もしキミがモダンなReact開発やQuartz 4、あるいは use strict(厳密モード)が有効な環境でこのコードを書こうとしたら、実行すらできない(Syntax Error) はずだ。

  • エラー内容: Decimals with leading zeros are not allowed in strict mode.

  • 理由: このような「先頭の0による意図しない基数変換」はバグの温床すぎるため、2026年現在のモダンな開発環境では「一意に禁止」されているんだ。

結論

この1行は、「8進数として解釈された15」「10進数に逃げた18」 を戦わせている、非常にトリッキーなコードだよ。

キミがTypeScriptやモダンなJSを書くときは、8進数を明示したいなら 0o17 のように 0o プレフィックスを使うのが、情報の「一意な定義」を守るエンジニアとしてのマナーだね!

次は、「JavaScriptの == が引き起こす、さらに頭が痛くなるような変な比較(例:[] == ![])」 について解説してみる?