C/C++ プログラマのための JavaScript 入門: 型変換
データ型についてもう少しだけ。 JavaScript の型変換は静的型付け言語に慣れている人には最も分かりにくい部分だと思います。 そこで型変換について整理しておきます。 例によって「プロローグ」で挙げた文献を頻繁に参照しています。 これらの文献を参照しながらご覧になることをお薦めします。
JavaScript では変数あるいはプロパティの型というものは存在しません。 またひとつの変数に異なるデータ型の値を格納することもできます。
var a = 1.2; WScript.Echo("a = " + a); a = "JavaScript"; WScript.Echo("a = " + a);
ある変数を参照するとき, どのデータ型として参照されるかは実行時のコンテキストによります。 以下にコンテキストによる型変換の例を示します。
値 文字列 数値 論理値 オブジェクト "" (空文字列) "" 0 false String オブジェクト "123" "123" 123 true String オブジェクト "xyz" "xyz" NaN true String オブジェクト 0 "0" 0 false Number オブジェクト 123 "123" 123 true Number オブジェクト NaN "NaN" NaN false Number オブジェクト Infinity "Infinity" Infinity true Number オブジェクト -Infinity "-Infinity" -Infinity true Number オブジェクト true "true" 1 true Boolean オブジェクト false "false" 0 false Boolean オブジェクト { x:1 , y:2 } (後述) (後述) true Object オブジェクト [ 1, 2, 3 ] "1,2,3" NaN true Array オブジェクト function() { } (関数リスト) NaN true Function オブジェクト null "null" 0 false - undefined "undefined" NaN false -
NaN, Infinity は初めて登場しました。 これらは数値の特別な値です。 NaN (Not a Number)は非数値(例えばゼロで割った値は NaN です)を, Infinity は無限大(-Infinity は負の無限大)を表します。 Number, String, Boolean, Function は各データ型に対応するコンストラクタ関数です。 Onject と Array については前回登場しましたが, 他のデータ型にも対応するコンストラクタ関数が存在します。
オブジェクトの文字列または数値への型変換は toString または valueOf メソッドの結果によります。 文字列への変換の場合, まず toString メソッドを試します(toString メソッドがない場合や返り値が適当でない場合は valueOf メソッドを試します)。 数値への変換の場合, まず valueOf メソッドを試します(valueOf メソッドがない場合や返り値が適当でない場合は toString メソッドを試します)。
コンテキストからはデータ型がはっきりしない場合があります。 例えば + 演算子や比較演算子(<, <=, >, >= など)は数値にも文字列にも使えます。 この場合はまず valueOf メソッドを試し次に toString メソッドを試します。 つまり, まず数値コンテキストと見なして評価するわけです(例外は Date オブジェクトです)。
WScript.Echo("1 + 2 =", 1 + 2); // 3 WScript.Echo("1 + \"2\" =", 1 + "2"); // "12" WScript.Echo("\"1\" + 2 =", "1" + 2); // "12" WScript.Echo("\"1\" + \"2\" =", "1" + "2"); // "12" WScript.Echo("true + 2 =", true + 2); // 3 WScript.Echo("11 < 2 =", (11 < 2).toString()); // false WScript.Echo("11 < \"2\" =", (11 < "2").toString()); // false WScript.Echo("\"11\" < 2 =", ("11" < 2).toString()); // false WScript.Echo("\"11\" < \"2\" =", ("11" < "2").toString()); // true WScript.Echo("\"11\" < true =", ("11" < true).toString()); // false WScript.Echo("\"11\" < \"true\" =", ("11" < "true").toString()); // true
+ 演算子の場合はオペランドの一方が文字列であれば文字列連結として機能します。 数値加算として機能するのは両オペランドとも文字列以外の場合です。 比較演算子の場合はオペランドが数値以外であれば原則どおりまず数値への型変換を試します。 ただし比較演算子の両オペランドが文字列の場合は型変換を行いません。
型変換を行わない場合もあります。 JavaScript には同値演算子(===)と非同値演算子(!==)がありますが、 これらの演算子では型変換を行いません。
WScript.Echo("1 == \"1\" =", (1 == "1").toString()); // true WScript.Echo("1 === \"1\" =", (1 === "1").toString()); // false
データ型についての説明はこんなところでしょうか。 さて, 次回からようやくオブジェクトの話に入れます。 ちょっと一息入れてからまた再開したいと思います。