🍊

ブラウザの Console と node の解釈の相違

2022/09/25に公開

これは何

↓ のあたりについて、覚え書き

https://twitter.com/azu_re/status/1573914365233082368

https://github.com/nodejs/node/issues/44781

結局のところ

  • ブラウザの開発者コンソールだと {} を コードブロックと解釈する
  • node の REPL は {} をオブジェクトリテラルと解釈する

前提

  • +[]0 と等価
  • ({} + []) はオブジェクトに評価されれる
  • ({})0 は等価でない
+[] === 0
// true
({} + [])
// '[object Object]'
({}) === 0
// false

node 18.9.1 での実行キャプチャ

起きてたことと

https://github.com/nodejs/node/issues/44781

  • node の REPL では {} + [] === 0false になる
  • Chrome の開発者ツールでは {} + [] === 0true になる
    • Firefox でも同じだった

Firefox のキャプチャ

GitHub でのコメントと理解したこと

The REPL evaluates it as ({} + [] === 0) - note the parens. It's the difference between these two:

eval('{} + [] === 0')
true
eval('({} + [] === 0)')
false
Without the parens, the {} is an empty block, not an object literal. Replace it with {1 + 2 + 3} and you get the same result. edit: I didn't make it clear but what is actually compared is +[] === 0, the {} is a red herring.

Not really a bug, just mildly unexpected behavior.

https://github.com/nodejs/node/issues/44781#issuecomment-1257126635

  • {} をオブジェクトリテラルと解釈するか、空のコードブロックとして解釈するかで、評価が異なり結果がかわる
  • ブラウザのコンソールでは Issue のコードの {} はコードブロックとして評価される
  • node の REPL では Issue のコードの {} はオブジェクトリテラルとして評価されれる

ということは、あいまいさをなくせばよいはずなので。

in browser

const val = {} + [] === 0;
val === 0;
// false

Chrome の開発者コンソールのキャプチャ

in node repl

{;} +[] === 0
// true

node 18.9.1 での実行キャプチャ

おわりに

すっと頭に入ってこなかったのと red herring っていうコメントが良い表現だなと思ったので調べてみました。

IDE で補助されながら書いていると気付きにくい差なので、気付いたこと自体すごいなと思いました。

GitHubで編集を提案

Discussion