JavaScriptの「Object」「Global」オブジェクト、「NaN」「URI」エンコードの基本JavaScript標準ライブラリの使い方超入門(6)(3/4 ページ)

» 2016年11月01日 05時00分 公開
[金城俊哉]

任意の値を数値に変換する

 JavaScriptは、ソースコードの文脈を読み取って、適切なデータ型へ自動的に変換してくれます。「document.write(10);」とした場合は、数値の10を文字列に変換したうえで書き出してくれます。しかし、このような自動変換が思わぬ結果を招くこともあり、それがプログラムのバグ(不具合)の原因になることがあります。

 このようなことがないようにJavaScriptでは、プログラマー自身が明示的にデータ型の変換を行うための、グローバルメソッドが用意されています。

Number()/parseInt()/parseFloat()の挙動の違いを確認する

Navigator

「Number()は任意の値を数値型に変換、parseInt()は文字列を整数値に変換、parseFloat()は文字列を浮動小数点数に変換するグローバルメソッドです。どれも『与えられた値を数値に変換する』処理を行いますが、細かな点で動作が異なる場合があります。まずは、次のプログラムで挙動を確認してみましょう」


特定の値を数値に変換する(parse.html)
Navigator

「それぞれの実行結果は右側にコメントとして書いておきました」


Driver

「まず(1)の『var str = '123abc';』ですが、数字と文字のミックスですね」


Navigator

「数字を含む文字列を変換するのですが、Number()メソッドはこれを解析することができず『NaN』を返してしまいます。一方、parseInt()、parseFloat()はどちらも『123』の部分を解析し、これを数値として返しています。ただし、これは先頭から半角の数字が連続している場合で、『abc123』の場合は解析できずに『NaN』が返されます」


Driver

「なるほど。続く(2)の『var hex = '0x333';』ですが、『0x』を指定して16進数としていますね」


Navigator

「16進数表記の『0x333』をそれぞれ変換しています。Number()とparseInt()メソッドはそれぞれ正しく解析して10進数の『819』を返していますが、parseFloat()メソッドは先頭の『0』だけを返しています。ですが、『var hex = 0x333;』のように数値リテラルにした場合は、3つのメソッドすべてが『819』を返します」


Driver

「(3)の『var exp = '1.23E+03';』ですが、これは指数表記ですか?」


Navigator

「浮動小数点の指数表現を変換しています。『1.23E+03』は『1.23×10の3乗』という意味なので『1230』になります。Number()とparseFloat()メソッドは正しく解析していますが、parseInt()メソッドは『e+2』を削除し、さらに小数点以下を切り捨てるので『1』が返されます」


Driver

「最後の(4)の『var dat = new Date();』は、ミリ秒単位で示される現在の日時を表す値ですね」


Navigator

「まずNumber()メソッドでDateオブジェクトのインスタンスを数値に変換しています。parseInt()とparseFloat()メソッドは、まったく解析できずに『NaN』を返しています。一方、Number()メソッドだけは、Dateのインスタンスが保持している『ミリ秒単位の経過時間』を返していているというわけです」


Memo NaNって何?

 NaN(ナン)は、Not A Numberの略で、数値ではないことを表す値です。厳密にいえばグローバルオブジェクトのプロパティです。

 NaNの初期値は非数であり、NaNはNaN自身を含むあらゆる数値と等しくないという特徴があります。parseInt()やparseFloat()などは、引数に指定した値が数値でない場合にNaNを返します。実際には、NumberオブジェクトのNumber.NaNプロパティの値を返しますが、JavaScriptでは、Number.NaNをNaNとして出力します。

 まあ、どちらにしたってプログラム上では関係のない細かい話ではありますが、NaNやNumber.NaNは自身とは等しくないので、「NaN === NaN」「Number.NaN === NaN」のように、「===」や「==」で等しいかを調べると、すべてfalseになります。NaNであるかを調べるには「isNaN(NaN)」のようにisNaN()関数を使います。


Memo Number()/String()/Boolean()の正体

 Number()String()Boolean()メソッドを使っていて気付かれたかもしれませんが、これらのメソッドと、ラッパーオブジェクトのNumber、String、Booleanを生成するコンストラクターは同じものです。ですので、次の2通りの書き方は、どれも同じ意味です。

ラッパーオブジェクトのNumber、String、Booleanを生成するコンストラクターは同じもの

 重要なポイントとして、これら3つのコンストラクターは、「new演算子を付けない場合は型変換を行う」処理を行います。ですので、次のように書いてもプログラムは動きますが、このように書くべきではありません。

 逆に、インスタンス化を行うときにnewを付けないと混乱のもとになりますので、インスタンス化のときはnewを付けるのが本来の姿です。

データ型の変換ではnewを付けない

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。