parseInt/parseFloatを使わないほうがいい理由の記事を読んだ
JavaScript で parseInt / parseFloat を使わない方が良い理由
読んだ。
これTwitterかなんかでバズってて自分も全然知らなかったのでとても勉強になった。
Math.truncを使う
まずMath.trunc
を初めて知った。
Math.trunc
を使うと小数点以下を切り捨てた整数を返す。
Math.trunc() - JavaScript | MDN
Math.floor
は「その数値を超えない一番大きな整数」だから、マイナス値のときの挙動が異なる。
Math.floor() - JavaScript | MDN
記事内ではMath.floor
を使わないほうがいいと書いてあるが、まあ用途によって必要なときはありそう。
parseIntとparseFloatは使わない
parseInt
は第二引数に指定した進数(2とか16とか)を10進数に変換するときにのみ使うのがよく、それ以外の場合は使わないほうがよい。
parseFloat
は以下。
簡単にまとめると、parseFloat は文字列の先頭からとにかく数字であると判断出来るところまで数値化する(ただし 16 進数、8 進数、2 進数は扱えない) のに対して、Number は文字列全体が数値であれば数値化し、そうでなければ NaN を返す(16 進数、8 進数、2 進数も扱える)という違いがあります。
数値として意味のある部分まで数値に変換するというのはなかなかすごいなと思う。
こんなん絶対バグの原因になるから使わないほうがいいやろ……と思ったけど、
const widthString = "120px"; // document.getElementById('element').style.width のような形で取得 const width = parseFloat(widthString); // 120;
こんな例もあるのか……。
String(0.0000005) === "5e-7" になるのは
たとえば 1234.56789 の場合、s は 123456789、k は 9(123456789 が 9 桁なので)、1234.56789 === 123456789 * 10^(-5) を満たすように n が 4 となります。
なるほど?
これにより、k <= n が成立するのは小数点がない場合のみになります。n がマイナスの場合、n の絶対値には小数点以下に 0 がいくつ続くかが入ります。その前提で再度 Number::toString の仕様を見ると、8 番目の処理で n が -5 以上であればゼロを続けることが明示されています。
一方、小数点以下に 0 が 6 つ以上続く場合は 9 番、10 番の処理に入ります。0.0000005 の場合は k === 1 ですので 9 番の処理に入ります。すなわち、s(この場合は '5')を追加し、0x65の文字コードすなわち 'e' を追加し、n === -6 ですので '-' 記号を追加した上で abs(n - 1) すなわち '7' を追加します。
なんもわからん……。