2.7 型変換

(1/1)
String型からNumber型への変換を考える女性
値を別のデータ型へ変換する
JavaScriptでは、同じ変数に異なるデータ型の値を代入できる。一方、演算時には値が別の型へ変わることもある。本節では暗黙の型変換の規則と、String、Number、Booleanなどを使う明示的な型変換を学ぶ。

目次

サンプル・プログラム

暗黙の型変換

「2.2 データ型 - 動的型付け」で紹介したように、JavaScriptでは動的型付けが行われる。演算子のオペランドに異なるデータ型が並んだ場合、演算できるよう暗黙の型変換を行う場合がある。

とくに加算演算子 + には注意が必要だ。どちらか一方がString型なら、もう一方も文字列に変換して結合する。たとえば 12 + '3' の結果は数値の15ではなく、文字列の '123' である。一方、減算などは文字列を数値に変換して計算する。

大小比較では、両方が文字列ならUnicodeのコード単位順で比較し、それ以外では主に数値へ変換して比較する。これは国語辞典の並び順とは限らない。等価演算子 == には独自の変換規則があり、0 == false はtrueになる。通常は型も比較する厳密等価演算子 === を使う。
暗黙の型変換
演算子意味
+一方がString型なら、もう一方も文字列に変換して結合する
-, *, /, %, **文字列などを数値に変換して計算する。変換できなければNaNになる
>, >=, <, <=両方が文字列ならUnicodeのコード単位順、それ以外では主に数値として比較する
==, !=型が異なると、規則に従って型を変換して比較する
!Boolean型に変換してから真偽を反転する。!!値で真偽値へ変換できる

typeconv1.html

  19: <script>
  20: //ページのロード時に実行
  21: window.onload = function() {
  22:     let a = 12.5;       //Number型
  23:     let s = '12.5';     //String型
  24:     let r;
  25:     document.getElementById('ret01').textContent = 'a = ' + a + '...' + typeof a;
  26:     document.getElementById('ret02').textContent = 's = ' + s + '...' + typeof s;
  27: 
  28:     //一方がString型なら、+は文字列を結合する
  29:     r = a + s;
  30:     document.getElementById('ret03').textContent = 'a + s ... ' + r + '...' + typeof r;
  31: 
  32:     //減算
  33:     r = a - s;
  34:     document.getElementById('ret04').textContent = 'a - s ... ' + r + '...' + typeof r;
  35: 
  36:     //乗算
  37:     r = a * s;
  38:     document.getElementById('ret05').textContent = 'a * s ... ' + r + '...' + typeof r;
  39: 
  40:     //除算
  41:     r = a / s;
  42:     document.getElementById('ret06').textContent = 'a / s ... ' + r + '...' + typeof r;
  43: 
  44:     //大小比較
  45:     r = a > s;
  46:     document.getElementById('ret07').textContent = 'a > s ... ' + r + '...' + typeof r;
  47: 
  48:     //等価
  49:     r = a == s;
  50:     document.getElementById('ret08').textContent = 'a == s ... ' + r + '...' + typeof r;
  51: 
  52:     //厳密等価
  53:     r = a === s;
  54:     document.getElementById('ret09').textContent = 'a === s ... ' + r + '...' + typeof r;
  55: 
  56:     //false
  57:     r = 0 == false;
  58:     document.getElementById('ret10').textContent = '0 == false ... ' + r + '...' + typeof r;
  59: 
  60:     //true
  61:     r = 1 == true;
  62:     document.getElementById('ret11').textContent = '1 == true ... ' + r + '...' + typeof r;
  63: 
  64:     //空文字
  65:     r = '' == false;
  66:     document.getElementById('ret12').textContent = '"" == false ... ' + r + '...' + typeof r;
  67: 
  68:     //null
  69:     r = null == false;
  70:     document.getElementById('ret13').textContent = 'null == false ... ' + r + '...' + typeof r;
  71: 
  72:     //NaN
  73:     r = NaN == false;
  74:     document.getElementById('ret14').textContent = 'NaN == false ... ' + r + '...' + typeof r;
  75: 
  76:     //undefined
  77:     r = undefined == false;
  78:     document.getElementById('ret15').textContent = 'undefined == false ... ' + r + '...' + typeof r;
  79: 
  80:     //undefinedの否定
  81:     r = !undefined;
  82:     document.getElementById('ret16').textContent = '!undefined ... ' + r + '...' + typeof r;
  83: }
  84: </script>

明示的な型変換

このように暗黙の型変換は複雑で、バグの温床になりかねない。
そこで、フォームから受け取った文字列を計算する場合などは、目的の型へ明示的に変換することをお勧めする。

Number() は文字列全体を数値として解釈するのに対し、parseInt() と parseFloat() は先頭から読める数値部分だけを変換する。変換できなければNaNになる。NaNは「数値ではない結果」を表すNumber型の特別な値であり、Number.isNaN() で確認できる。
明示的な型変換
関数/メソッド意味
String(値)値をString型に変換する。nullやundefinedにも使える
Number(値)値全体をNumber型に変換する。空文字や空白だけの文字列は0、変換できない文字列はNaNになる
parseInt(文字列, 基数)先頭の空白を除き、整数として読める部分をNumber型にする。10進数では基数に10を指定する
parseFloat(文字列)先頭の空白を除き、小数として読める部分をNumber型にする
Boolean(値)値をBoolean型に変換する。false、0、-0、0n、空文字、null、undefined、NaNはfalseになる

typeconv2.html

  19: <script>
  20: //ページのロード時に実行
  21: window.onload = function() {
  22:     let a = 12.5;       //Number型
  23:     let s1 = '12.5';    //String型
  24:     let s2 = '12.5a';   //String型
  25:     let r;
  26:     document.getElementById('ret01').textContent = 'a = ' + a + '...' + typeof a;
  27:     document.getElementById('ret02').textContent = 's1 = ' + s1 + '...' + typeof s1;
  28:     document.getElementById('ret03').textContent = 's2 = ' + s2 + '...' + typeof s2;
  29: 
  30:     //Number型→String型
  31:     r = String(a);
  32:     document.getElementById('ret04').textContent = 'String(a) ... ' + r + '...' + typeof r;
  33: 
  34:     //String型→Number型
  35:     r = Number(s1);
  36:     document.getElementById('ret05').textContent = 'Number(s1) ... ' + r + '...' + typeof r;
  37: 
  38:     //String型→Number型
  39:     r = Number(s2);
  40:     document.getElementById('ret06').textContent = 'Number(s2) ... ' + r + '...' + typeof r;
  41: 
  42:     //String型→Number型(整数)
  43:     r = parseInt(s2, 10);
  44:     document.getElementById('ret07').textContent = 'parseInt(s2, 10) ... ' + r + '...' + typeof r;
  45: 
  46:     //String型→Number型(小数)
  47:     r = parseFloat(s2);
  48:     document.getElementById('ret08').textContent = 'parseFloat(s2) ... ' + r + '...' + typeof r;
  49: 
  50:     //→Boolean型
  51:     r = Boolean(a);
  52:     document.getElementById('ret09').textContent = 'Boolean(a) ... ' + r + '...' + typeof r;
  53: 
  54:     //→Boolean型
  55:     r = Boolean(s1);
  56:     document.getElementById('ret10').textContent = 'Boolean(s1) ... ' + r + '...' + typeof r;
  57: 
  58:     //0→Boolean型
  59:     r = Boolean(0);
  60:     document.getElementById('ret11').textContent = 'Boolean(0) ... ' + r + '...' + typeof r;
  61: 
  62:     //空文字→Boolean型
  63:     r = Boolean('');
  64:     document.getElementById('ret12').textContent = 'Boolean("") ... ' + r + '...' + typeof r;
  65: 
  66:     //null→Boolean型
  67:     r = Boolean(null);
  68:     document.getElementById('ret13').textContent = 'Boolean(null) ... ' + r + '...' + typeof r;
  69: 
  70:     //undefined→Boolean型
  71:     r = Boolean(undefined);
  72:     document.getElementById('ret14').textContent = 'Boolean(undefined) ... ' + r + '...' + typeof r;
  73: 
  74:     //NaN→Boolean型
  75:     r = Boolean(NaN);
  76:     document.getElementById('ret15').textContent = 'Boolean(NaN) ... ' + r + '...' + typeof r;
  77: 
  78:     //空文字はNumber型の0になる
  79:     r = Number('');
  80:     document.getElementById('ret16').textContent = 'Number("") ... ' + r + '...' + typeof r;
  81: 
  82:     //先頭が数値でなければNaNになる
  83:     r = parseInt('abc12', 10);
  84:     document.getElementById('ret17').textContent = 'parseInt("abc12", 10) ... ' + r + '...' + typeof r;
  85: }
  86: </script>

練習問題

コラム:電話番号、ID番号

スマートフォンを使うペンギンのイラスト
電話番号やID番号は数字だけでできていても、足し算などには使わない識別子である。Excelへそのまま入力すると、Excelの自動解釈によって先頭の0が消えたり、長い番号が指数表記になったりすることがある。これはJavaScriptの暗黙の型変換とは別の動作である。

桁数をそろえるため先頭を0で埋めることは「ゼロ埋め」または「ゼロパディング」と呼ぶ。「ゼロサプレス」は、反対に先頭の不要な0を省くことだ。電話番号やID番号はString型で扱い、Excelでは入力前にセルの表示形式を「文字列」にするとよい。

参考サイト

(この項おわり)
header