JSこわい
"2" + 2 は? typeof null は? JavaScriptの理不尽だけを集めた28問。正解はぜんぶ、本物のエンジンの回答です。
- ❓ 全28問の4択
- 🔊 音あり
- 💻 エンジニア向けネタ
- 🆓 無料・登録不要
これから、JavaScriptが
本当に返す値を当ててもらいます。
😱 途中で「こわい」と言っても
問題は続きます
ぜんぶ実話です(実行できます)
遊び方
- ▶️ はじめるJavaScript の式が1つ出ます。これを評価すると何が返るかを、4つの選択肢から選びます。
- 👆 4択をタップ選んだ瞬間に判定。正解は緑に光り、外すと画面がガタッと揺れて、正しい答えが緑で示されます。答え直しはできません。
- 💡 種明かしを読む正解でも不正解でも、なぜそうなるのかが1行で出ます。読んだら「つぎへ」。キーボードなら Enter で進めます。
3問連続で正解すると🔥連続の表示が出て、正解音が少しずつ高くなります。28問終わると称号が出て、「結果をシェア」で送れます。
称号一覧 — 全5段
28問を解き終えると、正解数に応じた称号とひとことが出ます。いちばん下の称号がいちばん幸せそうなのが、このクイズの肝です。15問以上でファンファーレが鳴ります。
JSエンジンご本人28問
全問正解。ひとことは「もう人間には戻れません」。
仕様書の側の人24問〜
闇を見ても動じない心ができあがった人。ここまで来ると、隣の人に出題する側です。
闇に目が慣れた人15問〜
エンジンの気持ちが分かってきた頃。後半戦の闇で何問拾えたかで差がつきます。
JSこわい(正常)8問〜
ひとことは「JS、こわいですよね。わかります」。ふつうの感覚の持ち主です。
心のきれいな人〜7問
その素直さ、JSに壊されないでください。数学として正しい答えを選んだ人ほどここに来ます。
つくりの話
足すと文字列、引くと数値
1問目は "2" + 2。答えは文字列の "22" です。2問目の "2" - 2 は、数値の 0。+ には「文字列をつなぐ」役目もあるので文字列が勝ち、- にはその役目がないので両方を数値に直して計算します。同じ見た目の演算子なのに、人格がまるで違う。JavaScript の理不尽は、たいていこの「型の自動変換」から始まります。
こういう奇妙な挙動を集めてクイズにする遊びは、海外のエンジニアのあいだでは定番のネタです。JSこわいはその日本版で、名前は落語の「まんじゅうこわい」から。こわいこわいと言いながら、28問ぜんぶ食べてもらう作りです。
正解は人間が書かない。エンジンに聞く
理不尽を扱うクイズが、理不尽の中身を書き間違えていたら目も当てられません。いちばん怖いのは、正解データの写し間違いです。
そこで、28問の式を実際のブラウザの JavaScript エンジンで評価し、その結果と出題データの正解が一致するかを機械で照合しています。画面に答えを出すときの書式(文字列は "22" のように引用符つき、配列は [1, 10, 8, 9] の形、それ以外はエンジンが印字するとおり)を決める処理を1つだけ用意し、照合もそれを通して行います。文字列の "22" と数値の 22 はクイズとしては別の答えなので、書式がずれると正解キーの検証そのものが崩れるからです。4つの選択肢のうち2つが偶然同じ表示になって、実質3択に崩れていないかも同じ照合で確かめています。
同じ見た目で、答えが違う2問
[] + {} の答えは "[object Object]"。そのすぐ次に出る {} + [] は 0 です。行の先頭に置かれた {} は、オブジェクトではなく中身が空のブロック文として読まれて消え、残った +[] が 0 になります。行頭かどうかで意味が変わるこの非対称こそが最恐ポイントなので、あえて2問並べました。
typeof null が直らない理由
typeof null が "object" になるのは、1995年の最初の実装からあるバグです。初期のエンジンは値の種類を下位ビットの目印で見分けていて、オブジェクトの目印は 0 でした。null は中身がすべて 0 なので、目印を読むとオブジェクトに見えてしまったわけです。
後に "null" を返すよう直す案も出ましたが、採用されませんでした。世界中の Web サイトがこの挙動を前提に書かれてしまっていて、直すと壊れるからです。バグでも、みんなが頼ったら仕様になる。種明かしの「互換性のため、永遠に直せません」は、そういう意味です。
冤罪は着せない
0.1 + 0.2 が 0.30000000000000004 になる問題だけは、JavaScript のせいではありません。0.1 も 0.2 も二進法では割り切れない循環小数なので、小数を二進法で持つ言語ならどれでも同じことが起きます。種明かしにも「JSに限らず浮動小数点の宿命」と書いて、ちゃんと免罪しています。
誤答は3系統で作る
4択の外れ選択肢は、適当に作るとすぐ見抜かれます。"2" + 2 なら、数学どおりの 4(素直な期待)、数値の 22(型だけ間違える人を釣る半分の正解)、NaN(JSだからどうせ壊れているという先入観)の3系統です。
効くのは3つ目です。中盤まで解くと、誰でも「JSは信用できない」と学習します。そこへ 1 < 2 < 3 のような、実はたまたま素直に true になる問題を置くと、疑い深さのほうが罠になります。種明かしの「疑いましたね?」はそのためのひとことです。このクイズでいじっているのは、理不尽そのものより「どこまで信じていいか」の距離感です。
出題順は「こわさの質」の順
28問は難易度順ではありません。序盤は文字列と数値の小さな嘘。中盤に浮動小数点や NaN === NaN のような「理由を聞けば納得できる世界の真実」を挟んで、いったん安心させます。14問目を過ぎると下の一言が「後半戦。ここからが本当の闇です」に変わり、{} + [] や parseInt(0.0000005) のような、理由を聞いても納得しにくい領域に入ります。最終問題は、こわいというよりご褒美です。
答え直しができない理由
外した直後に、反射で正解のボタンを押してしまうことはよくあります。1問につき最初のタップだけを受け付け、それ以降の選択肢はすべて押せなくしています。答えていないのに「つぎへ」で飛ばすこともできません。1問の重みが大きいクイズでは、ここが甘いとスコアが信用されなくなります。
シェアするのは、スコアより問題
結果のシェア文には、スコアと称号のほかに最終問題の式をそのまま入れています。タイムラインで見て気になるのはスコアより問題のほうで、見たエンジニアは答えを確かめずにいられないからです。答えはここには書きません。ヒントは、黄色くて甘い果物です。
楽しみ方
- まず直感で全部答える:考え込むより、1周目は勢いで。種明かしを読んでからの2周目で点がどれだけ伸びるかが、このクイズの手ごたえです。
- 種明かしを人に話す:
[10, 9, 8, 1].sort()の答えと理由を説明できれば、明日の雑談のネタになります。 - 新人研修や勉強会で回す:28問すべてに1行の理由がつくので、「これ全部説明できる?」という問題集として使えます。
- 非エンジニアと一緒に解く:数学として正しい答えを選ぶ人ほど外れます。隣のエンジニアの顔が3問目あたりから真顔になるのも見どころです。
- コンソールで確かめる:疑わしい問題は、ブラウザの開発者ツールに貼ってそのまま実行できます。
よくある質問
本当にこの答えになるんですか?
なります。出題の式はどれも JavaScript の仕様どおりに評価した結果で、ひっかけのために作った答えはありません。疑わしければ、ブラウザの開発者ツールのコンソールに式を貼ってみてください。
{} + [] だけコンソールで答えが違います
この問題は、行の先頭の {} が「空のブロック」として読まれる、文としての評価が前提です。実行環境によっては、行頭の { をオブジェクトとして読む工夫をしているため、別の結果が出ることがあります。
音が出ません
効果音はブラウザの中で合成していて、最初に画面に触れるまでは鳴りません。iPhone は本体の消音(マナーモード)がオンだと Web ページの音も鳴らないことがあります。
自己ベストはどこに保存されますか?
お使いのブラウザの中だけに保存され、サーバーには何も送りません。別の端末やブラウザには引き継がれず、ブラウザのデータを消すとリセットされます。
最終更新