LoginSignup
11
5

More than 3 years have passed since last update.

JavaScriptで数値への変換あれこれ

Last updated at Posted at 2015-05-21

JavaScriptで、何かを整数に変換するときに、いくつかの方法があります。fooに値が入っているとして、

  1. foo-0
  2. +foo
  3. parseFloat(foo)
  4. Number(foo)

のようにして数値化したとすると、結果が違ってくるパターンはあるのでしょうか。

ToNumber

1、2、4については、内部で行われる変換にToNumber(仕様書9.3)という名前が付いています。中身としては、

  • undefined→NaN
  • nullとfalse→+0
  • true→1
  • 数値ならそのまま
  • ObjectはvalueOf、そしてtoStringの順で変換を試み、得られたプリミティブを改めてToNumberにかける

文字列の場合(仕様書9.3.1)

文字列の場合は、前後のスペースを無視して、全体が

  • 10進法の整数または小数
  • 1.2e5のような指数表記
  • 0xで始まる16進整数

のいずれかになれば、それを数値に変換します。一方、そうでなければNaNを返します。

なお、0を引き算しても、(-0という特殊な値を含めて)数値は変化しません(仕様書11.6.3)。つまり、上の1、2、4は、fooに何が入っていようが同じ結果となります。

parseFloatの中身

parseFloatは、引数として文字列を取るのが前提なので、ToStringという内部操作(仕様書9.8)で文字列とした上で解釈します。なお、parseFloatでの解釈は上のToNumberとは違って、以下のようになっています(仕様書15.1.2.3)。

  • 16進数を受け付けない。
  • 数字以外のものが現れたら、そこより手前だけで評価する。

なお、ToStringの結果は、''.concat(foo)で得ることができます1

結果が違う場合

両者で結果が違う場合を下に挙げてみます。

  • null、true、false…ToStringでそれぞれの文字列になるので、parseFloatの結果はNaNです。
  • 16進文字列…最初の0だけがparseFloatに解釈されて、0を返します。
  • 途中に別な文字が入っている文字列…parseFloatは別な文字の手前までを解釈しますが、ToNumberはNaNとします。
  • 数値の-0…ToStringで'0'となってしまうので、parseFloatの結果は0を返します。
  • valueOf()toString()が違う結果を返すオブジェクト…標準のDateがこんなオブジェクトです。

原典

JavaScriptのもととなっているECMAScriptの言語仕様については、Ecmaのサイトで公開されていますし、和訳版も書籍として入手可能です。


  1. よく文字列化にfoo + ''String(foo)が使われますが、これらはToStringと結果が一致しないことがあります。 

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5