以下の記事が話題になった
NaN === NaNはfalseであるconsole.log(NaN == false); // → false- グローバルオブジェクトにある
isNaNとNumber.isNaNは挙動が違う - 配列の
indexOfでNaNは見つけられない
ということさえ覚えておけばよさそうで、あとはやろうと思えばNaN === NaNをboolean以外にもできる(まぁやらないよね)っていう話だった
ところで
このブログの中の余談1にあったNaNのビット表現を説明する箇所で、以下の検証コードを挙げられていたが、自分の知識不足で何をしているのかがわからなかった

なので、ここを理解するようにする
Float64ArrayとかUint8Arrayとか
Float64ArrayはArrayBufferに格納されたバイト配列の各8バイトを浮動小数点としてみなすというもの
次にUint8ArrayはArrayBufferに格納されたバイト配列の各1バイトを0 から 255までの値としてみなすというもの
例えば、new ArrayBuffer(16)の場合、Float64ArrayとUint8Arrayの関係は以下のようになっている

コードを読み解く
最初にFloat64Arrayのコンストラクタ引数に1を指定しているので8バイトの浮動小数点がはいるよと宣言しており
そこにNaNを代入し、Uint8Arrayで宣言した各1バイトをみると
console.log(charView.join(',')); // → 0,0,0,0,0,0,248,127のようになっている
リトルエンディアンなので、逆から並べてビット表現をみると次の図の(1)のようになる

このとき、charView[6] = 0xf0;をした場合(図の(2))では指数部のビットがすべて 1 のままだが、仮数部が全て0なのでInfinityになる
次に、charView[6] = 0xf4;をした場合(図の(3))は指数部のビットがすべて 1 のままで、仮数部が全て0ではないのでNaNになる
このように、NaNは複数通りのビット表現を持つことが許されている
ちなみに、理由はそういう仕様だから
という説明をしていたことが理解できた
他参考記事
https://tc39.es/ecma262/#sec-islooselyequal
https://yosuke-furukawa.hatenablog.com/entry/2018/01/30/174425