Javascript 文字列・数値 扱い一覧(変換・検索・置換・削除など)

JavaScriptの文字列や数値の扱いは、結構ややこしくて、いろんなサイトで説明してくれているのですが、1ページに記載されている情報が少なく、色々なページを見ないといけないので、出来るだけ1ページに纏めました。 でも、内容が結構多いのでアコーディオン方式にして見やすくしました。

文字列

宣言 『’』『`』『”』

シングルクォーテーション

  • シングルクォーテーションで括ると文字列となる。
  • シングルクォーテーション内でシングルクォーテーションを使う場合エスケープ処理(\)が必要だが、ダブルクォーテーションやバックティックならエスケープ処理(\)は不要。
let str1='abc';
console.log('a\'b\'c');    //-> a'b'c
console.log('a"b`c');     //-> a"b`c

ダブルクォーテーション

  • ダブルクォーテーションで括ると文字列となる。
  • ダブルクォーテーション内でダブルクォーテーションを使う場合エスケープ処理(\)が必要だが、シングルクォーテーションやバックティックならエスケープ処理(\)は不要。
let str2="def";
console.log("d\"e\"f");   //-> d"e"f
console.log("d'e`f");     //-> d'e`f

バックティック 変数・式可

  • ES6から追加された記述方法でテンプレートリテラルとも言われる。
  • ダブルクォーテーションやシングルクォーテーションと同じで文字列宣言出来る。
  • ダブルクォーテーションやシングルクォーテーションとの違いは変数や数式も${}を使い入れ込めるのでプログラムば見やすくなりバグを減らせる。(substitution)
  • テンプレートリテラル内の改行(\n)は実際の出力でも改行となる。
  • しかしダブルクォーテーションやシングルクォーテーションと比べると演算速度が若干遅いので変数を使わない時は、ダブルクォーテーションやシングルクォーテーションを使うのがベスト。
  • バックダブルクォーテーション内でバックティックを使う場合エスケープ処理(\)が必要だが、シングルクォーテーションやダブルクォーテーションならエスケープ処理(\)は不要。
let str3=`ghi`; 
let value1=250;
console.log(`値段は、${value1}円です。`);       //-> 値段は、250円です。 
console.log(`値段は、${value1*1.08}円です。`);  //-> 値段は、270円です。
console.log(`g\`h\`i`);                         //-> g`h`i
console.log(`g'h"i`);                           //-> g'h"i
連結 +

文字列は+で連結

let str1=`abc`;
let str2=`def`;
let a = 987
console.log(str1+str2);    //-> abcdef
console.log(str1+'ghi');   //-> abcghi
console.log(str1+str2+a);  //-> abcdef987
console.log(str1+`ここに${a}入る`+str2);  //->abcここに987入るdef
長さ .length プロパティ
let str1=`abc`;
let a = 987
console.log(str1.length);                    //-> 3
console.log('123あいう'.length);             //-> 6
console.log((str1+'ghi'+a).length);          //-> 9  
console.log((str1+`ここに${a}入る`).length); //-> 11
検索(位置).indexOf()メソッド

指定文字列の位置を返す

  • 指定文字列を左から探して最初にマッチして位置を返す。
  • 文字列の位置は左から0から始まる。
  • 全角文字も半角文字も1文字と見る。
  • ”で検索してもエラーにならず一番左の文字列と一致した時と同様に0を返す。
let str1=`abcあいう`;
let a = 987
console.log(str1.indexOf('a'));                 //-> 0
console.log(str1.indexOf('あい'));              //-> 3 
console.log((a+str1).indexOf('あい'));          //-> 6
console.log((`efg${a}`+str1).indexOf('あい'));  //-> 9
console.log((str1+str1+str1).indexOf('あい'));  //-> 3
console.log(str1.indexOf(''));                  //-> 0
検索(有無).startsWith() .endsWith()メソッド

指定文字列で始まっているか、終わっているかの判定をし、trueかfalseを返す。

let str1=`abcあいう`;
let a = 987
console.log(str1.startsWith('abcあ'));           //-> true
console.log(str1.startsWith('bc'));              //-> false
console.log((`${a}def`+str1).startsWith('98'));  //-> true
console.log(str1.endsWith('あいう'));            //-> true
console.log(str1.endsWith('あい'));              //-> false
判定 正規表現 .search() .match() .matchAll() exec()メソッド

serch(regExp)は正規表現に最初にマッチした位置を返す。

  • マッチしなかったら-1を返す。

match(regExp) 正規表現に最初にマッチした値とプロパティを持つ配列を返す

matchAll(regExp)は正規表現にマッチした全ての値のそれぞれの値とプロパティを持つ配列を返す。

  • 2つ以上マッチしたら、2次元配列になる。

exec()は1つしかマッチを返さないが、() ()内を記憶し、配列内に入れて返す。

  • マッチ部分の検証やデバッグなどで便利。
console.log("test1test2".search( /st(\d?)/g));
//-> 2
console.log("test1test2".match( /t(e)(st(\d?))/g));
//-> [ 'test1', 'test2' ]
console.log([..."test1test2".matchAll( /t(e)(st(\d?))/g)]);
//-> [['test1','e','st1','1', index: 0, input: 'test1test2', groups: undefined ],
//    ['test2','e','st2','2', index: 5, input: 'test1test2', groups: undefined ]]
console.log([..."test1test2".matchAll( /t(e)(st(\d?))/g)][1]);
//->['test2','e','st2','2', index: 5, input: 'test1test2', groups: undefined ]
console.log([..."test1test2".matchAll( /t(e)(st(\d?))/g)][1].length);
//-> 4
console.log([..."test1test2".matchAll( /t(e)(st(\d?))/g)][1]['input']);
//->test1test2
console.log(/(\d+).(\d{2})/.exec("12.345"));
//->console.log(/(\d+).(\d{2})/.exec("12.345"));

その他正規表現が使えるメソッド等

  • str.split(regExp)
  • str.replace(regExp, str)
  • regExp.test(str)
  • $(regExp). *jQuery記法がある。
置換 .replace()メソッド

str.replace(検索文字、置換文字)

  • 検索文字は、べたの文字か正規表現。
  • 正規表現を使いgオプションを使うと、マッチした文字全てを置き替える事が出来るので、非常によく使われる。
  • 下のコードの/dog/gが/正規表現/gオプション。
  • 正規表現の時は『’』の代わりに『/』を使う。
let str1 ='dog1 dog2 dog3';
console.log(str1.replace('dog','cat'));     //-> cat1 dog2 dog3
console.log(str1.replace(/dog/g,'cat'));    //-> dog1 dog2 dog3

let str2 = 'The dog
always barks at
me.'; consolde.log(str2.replace(/
/g, '\n')); //->私の名前は //太郎です。 //年は18歳です。
切出・文字削除 .substring() .slice() .substr()メソッド

substring(開始位置、終了位置)

  • 3文字の最終文字を読む時は、開始位置=3、終了位置=4
  • 開始位置や終了位置が負数の時は0とみなされる。
  • 開始位置>終了位置の場合、自動的に入れ替える。

slice(開始位置、終了位置)

  • 以下以外はsubstringと同じ。
  • 負数の時は後ろから数える。
  • 開始位置>終了位置の場合、スペースを返す。

【非推奨】substr(開始位置、文字数)

  • 『“』内の文字には使えない。 開始位置が負数の時は後ろから数える。
let str1="0123456789"
console.log(str1.substring(2,4));   //-> 23
console.log(str1.slice(2,4));       //-> 23
console.log(str1.substr(2,4));      //-> 2345
console.log(str1.substring(-4,-1)); //->     *-4も-1も0とみなされるので出力なし。
console.log(str1.slice(-4,-1));     //-> 678
console.log(str1.substr(-4,2));     //-> 67
console.log(str1.slice(0,3));       //-> 012 先頭3文字切出し。 文字数が少なくてもあるだけ切出す。
console.log(str1.slice(-2));        //-> 89 末尾2文字切出し。 文字数が可変でもOK。
console.log(str1.slice(3));         //-> 3456789 先頭3文字削除。 文字数が可変でもOK。
console.log(str1.slice(0,-2));      //-> 01234567 末尾2文字削除。 文字数が可変でもOK。
分割 .split()メソッド

正規表現か文字とマッチした所で文字列を分割して配列で返す。

  • マッチしなければ、元の文字を長さ1の配列で返す。
var regExp = /[\/\.\-]/;
console.log('2022/03/04'.split(regExp));     //-> [ '2022', '03', '04' ]
console.log('2022-03-04'.split(regExp));     //-> [ '2022', '03', '04' ]
console.log('2022.03.04'.split(regExp));     //-> [ '2022', '03', '04' ]
console.log('2022.03.04'.split('.'));        //-> [ '2022', '03', '04' ]
console.log('2022.03.04'.split('a'));        //-> [ '2022.03.04' ]
console.log('2022.03.04'.split('a').length); //-> 1
空白(エスケープシーケンス)削除 .trim() .trimStart() .trimEnd()メソッド

trim()

  • 文字列の先頭・末尾から空白を取り除く。
  • 空白とは半角スペース、全角スペース、\n、\r、\t、\v、\f。 これらは取り除かれる。 trimStart, trimEndも同じ。
  • \bと\0(null)は取り除かれない。
  • 下の例では、appleの後ろに全角スペースも入っている。

trimStart()

  • 文字列の先頭から空白を取り除く。

trimEnd()

  • 文字列の先頭・末尾から空白を取り除く。
console.log('**' + '   apple    ' + '**');
//-> **   apple    **
console.log('**' + '   apple    '.trim() + '**');
//-> **apple**
console.log('**' + '   apple    '.trimStart() + '**');
//-> **apple    **
console.log('**' + '   apple    '.trimEnd() + '**');
//-> **   apple**
茶色の□が全角スペース。
先頭ゼロフィル padStart()メソッド

padStart(文字数, 埋める文字)

console.log('1234567'.padStart(10, '0'));      //-> 0001234567
console.log('-1234567'.padStart(10, '0'));     //-> 00-1234567
console.log('1234567'.padStart(20, 'ichiri')); //-> ichiriichirii1234567
console.log('1234567'.padStart(10, 'あ'));   //-> あああ1234567
console.log('1234567'.padStart(10, 9));      //-> 9991234567
ASCII変換 charCodeAt()メソッド

str.charCodeAt(文字位置)

  • 1文字ずつASCII変換。
  • 変換結果は10進数。
  • toString(16)で16進数に変換。
a='0123abcd';
for (let i = 0; i < a.length; i++) {
    process.stdout.write(a.charCodeAt(i).toString(16)); 
    process.stdout.write(' '); 
}
//-> 30 31 32 33 61 62 63 64 
process.stdout.write('\n'); 
console.log(a.charCodeAt(0));                      //-> 48
console.log(typeof(a.charCodeAt(0)));              //-> number
console.log(a.charCodeAt(0).toString(16));         //-> 30
console.log(typeof(a.charCodeAt(0).toString(16))); //-> string
文字列比較 ===

一致するかどうかは 『===』を使うのが最も正確。

  • 『==』の場合は、比較対象が数値の場合、文字列の数字を数値に自動変換する。
  • また、不等号を使うと文字列を先頭から1文字づつASCIIコード化した数値として比較していく。
  • 下の例では"a"は0x61に対し"A"は0x41なので、trueとなる。
  • 大文字小文字関係なく比較する時は、全部大文字に変換(toUpperCase())して比較する。
  • 小文字に変換して比較すると上手く比較できない場合がある。
const str1 = "abcde";
const str2 = "abcde";
const str3 = "123";
console.log(str1 === str2);     //-> true
console.log(str1 === "abcde");  //-> true
console.log(str1 === "ABCDE");  //-> false
console.log(str3 == 123);       //-> true
console.log(str3 === 123);      //-> false
console.log("a" > "ABCDE");  //-> true
console.log("ABCDE".toUpperCase() === "abcde".toUpperCase());
                                //-> true
長い文字列の折り返し 『+』か『`』

『``』バックティック(テンプレートリテラル)

  • HTML文字列を宣言する時などに便利。
  • バックティック内で、Enterで改行すると、そのまま改行として認識されるので、複数行文字列を続けていける。 しかもHTMLとしては空白(\n\r\f スペース等)は無視されるので、ソース内で見やすく配置しても問題ない。

『+』

  • HTML文字列でない場合はこれが一番いいと思う。

『\』バックスラッシュ

  • あまり使わない方が良い。 ソース内でバックスラッシュで複数行にした時、先頭にタブやスペースを入れるとそのまま表示される。 先頭に詰めるとソースが読みづらくなる。
const str1 = `

これはリンゴです。
リンゴは赤いものや黄色いものがあるが どれもおいしいです。

`; const str2 = `これはリンゴです。 リンゴは赤いものや黄色いものがあるが どれもおいしいです。`; console.log(str2); //->これはリンゴです。 リンゴは赤いものや黄色いものがあるが どれもおいしいです。 document.write(str1); // html内でこのコマンドを実行すると、以下の図の様に表示される。
『+』を使ったstr3はソースも見やすく、表示も正しいです。
『\』を使ったstr4は、ソースは見やすいですが、スペースが入ってしまっていて正しくありません。
『\』を使ったstr5は正しく表示されますが、ソースのインデントが無く、見づらいです。
*しかも『\』はEnglighterJSでは正しく認識されず、表示の色が変になっています。
const str3 = "これはリンゴです。\n" +
             "リンゴは赤いものや黄色いものがあるが" +
             "どれもおいしいです。";
const str4 = "これはリンゴです。\n\
             リンゴは赤いものや黄色いものがあるが\
             どれもおいしいです。";
const str5 = "これはリンゴです。\n\
リンゴは赤いものや黄色いものがあるが\
どれもおいしいです。";
console.log(str3);
//-> これはリンゴです。
リンゴは赤いものや黄色いものがあるがどれもおいしいです。
console.log(str4);
//-> これはリンゴです。
             リンゴは赤いものや黄色いものがあるが             どれもおいしいです。console.log(str5);
//-> これはリンゴです。
リンゴは赤いものや黄色いものがあるがどれもおいしいです。
文字列プリミティブとStringオブジェクト
  • 文字列は文字列プリミティブと言われます。
  • Stringオブジェクトは文字列プリミティブにプロパティとメソッドが内蔵されたようなものです。
  • 余り使用されることはありません。
let s1 = 2;
var s2 = String(s1);
var s3 = new String(s1);    // String オブジェクトを生成

console.log(typeof s1);     // -> number
console.log(s2);            // -> 2
console.log(typeof s2);     // -> string
console.log(s3);            // -> [String: '2']
console.log(typeof s3);     // -> Object

数値

数値の型 倍精度小数点数

JavaScriptではBigIntと宣言しなければ全て64bit倍精度小数点数

  • 1や100等の整数に見えても内部は浮動小数点数で誤差を持っている。 誤差は数値*±Number.EPSILON。
console.log((0.1).toFixed(50));
//-> 0.10000000000000000555111512312578270211815834045410
console.log((-0.1).toFixed(50));
//-> -0.10000000000000000555111512312578270211815834045410
console.log((0.1*3).toFixed(50));
//-> 0.30000000000000004440892098500626161694526672363281
let a =0.1+0.2;
console.log(a == 0.3);
//=> false aには誤差があるので。
console.log(Number.MAX_VALUE);  //-> 1.7976931348623157e+308 絶対値の最大の数字
console.log(Number.MIN_VALUE);  //-> 5e-324 絶対値の最小の数字
console.log(Number.EPSILON);    //-> 2.220446049250313e-16 誤差係数
console.log(Number.EPSILON ===2**(-52));  //-> true 誤差は仮数の1bit分

64bitの形式

  • IEEE754準拠 倍精度浮動小数点数 符号(1bit)+指数(11bit)+仮数(52bit)

BigInt

  • 整数のみ使用できます。
  • 変換方法は数字の末尾にnを付けるか、BigInt()で変換する。
  • BigInt型の場合はBigInt同士しか計算できません。
  • 割り算は商しか出さない。%(MOD)と同じ。
  • 1,073,741,824bitのようです。
console.log(typeof 123n);           //-> bigint
console.log(123n == 123);           //-> true
console.log(123n === 123);          //-> false
console.log(123n === BigInt(123));  //-> true
console.log(12n/3n);                //-> 4n
console.log(12n/5n);                //-> 2n
console.log(12 % 5);                //-> n
console.log(12n/3);                 //-> TypeError: Cannot mix BigInt and other types, use explicit conversions
記法ES2021から区切りで『_』が使えるようになった。実際の計算等では無視される。
console.log(-123);        //-> -123 10進表記
console.log(.123);        //-> 0.123 10進表記
console.log(.123e+3);     //-> 123 指数表記
console.log(0b1111_0011); //-> 243  2進表記
console.log(0o721);       //-> 465  8進表記
console.log(0721);        //-> 465  8進表記、先頭0の次が7以下の場合
console.log(0821);        //-> 821  10新表示、先頭0の次が8か9の場合
console.log(0x0721);      //-> 1825 16進表記
console.log(0x07_21);     //-> 1825 16進表記
console.log(123_456_789); //-> 123456789 10進表記、何もつけなければ10進
console.log(123,456,789); //-> 123 456 789
数字から文字列変換 toString(), toFixed(), toPrecision() etc

Number.toString(進数)

  • 最も一般的に使われる数値から文字列変換。
  • ()の中に16を入れると16進数の文字列。何も入れなければ10進数の文字列に変換。
  • 先頭に直接数値を入れる時は小数表示にしなければならない。
  • 絶対値\(10^{21}\)以下。
  • \(2^{32}\)以上必要とする誤差は無視される。
a=20;
console.log(a.toString());        //-> 20
console.log(20..toString());      //-> 20
console.log(20..toString(16));    //-> 14
console.log(20.12.toString(16));  //-> 14.1eb851eb851f

Number.toFixed(桁数)

  • ()の中に小数点以下の桁数を入れる。
  • 絶対値\(10^{21}\)以下。
  • 誤差があるので、完全な四捨五入にはならない。
  • 変換精度は良いが、計算では意味がない。
console.log((-20.).toFixed(3));     //-> -20.000
console.log((1.23e+3).toFixed(3));  //-> 1230.000
console.log(2.34.toFixed(1));       //-> 2.3
console.log(2.55.toFixed(1));       //-> 2.5
a=2.0000000000000010000;
console.log(a.toFixed(25));  //->2.0000000000000008881784197
console.log(a.toString());   //->2.000000000000001
console.log(2.0000000000000008881784197===2.000000000000001); //->true

Number.toExponential(桁数)

  • eを使った指数表現の文字列に変換。
  • ()内は小数点以下の桁数。
console.log(20..toExponential(3));         //-> 2.000e+1
console.log((-0.01234).toExponential(1));  //-> -1.2e-2

Number.toPrecision(桁数)

  • ()内の桁数の有効数字に変換する。
  • 必要に応じて指数表現になる。
  • 精度はtoFixed()と同じ
console.log(1.2345.toPrecision(4));       //-> 1.234
console.log(12345..toPrecision(4));       //-> 1.235e+4
console.log(0.00123.toPrecision(2));      //-> 0.0012
console.log(0.0000000123.toPrecision(2)); //-> 1.2e-8
console.log(2.34.toPrecision(2));         //-> 2.3
console.log(2.55.toPrecision(2));         //-> 2.5

Number.toLocaleString(フォーマット記述)

  • 指定したフォーマットに変換する。
  • ()に何も入れなければ3桁ごとにカンマ区切りとなる。
console.log(1234567..toLocaleString("ja-JP", 
           {style:"currency", currency:"JPY"}));  //-> ¥1,234,567
console.log(1234567..toLocaleString());           //-> 1,234,567 
文字列から数値変換 Number(), parseInt(), parseFloat() etc

parseFloat()とNumber()

  • 共に()内の文字列を数値に変換する。
  • parseFloatは数字でない文字までを数値に変換する。
  • NumberはBigInt形式を変換でもnを文字として認識し変換しない。
  • Numberの方が約7倍速い。
  • parseFloatは16進や2進を変換できない。
function test(str){
  return {parseFloat: parseFloat(str), Number: Number(str)};
} 
console.log(test('0.0000000000000000000000000001'));
                                //-> { parseFloat: 1e-28, Number: 1e-28 }
console.log(test('-1.234'));    //-> { parseFloat: -1.234, Number: -1.234 }
console.log(test('2e+3'));      //-> { parseFloat: 2000, Number: 2000 }
console.log(test('32bit'));     //-> { parseFloat: 32, Number: NaN }
console.log(test('2n'));        //-> { parseFloat: 2, Number: NaN }
console.log(test('0xff'));      //-> { parseFloat: 0, Number: 255 }
console.log(test('ff'));        //-> { parseFloat: NaN, Number: NaN }
console.log(test('0b1010'));    //-> { parseFloat: 0, Number: 10 }
console.log(test('0b10_10'));   //-> { parseFloat: 0, Number: NaN }
console.log(test('ichiri'));    //-> { parseFloat: NaN, Number: NaN }
console.log(test('-001.23'));   //-> { parseFloat: -1.23, Number: -1.23 }
console.log(test('undefined')); //-> { parseFloat: NaN, Number: NaN }
console.log(test(undefined));   //-> { parseFloat: NaN, Number: NaN }
console.log(test('NaN'));       //-> { parseFloat: NaN, Number: NaN }
console.log(test(NaN));         //-> { parseFloat: NaN, Number: NaN }
console.log(test('Infinity'));  //-> { parseFloat: Infinity, Number: Infinity }
console.log(test(Infinity));    //-> { parseFloat: Infinity, Number: Infinity }
console.log(test('null'));      //-> { parseFloat: NaN, Number: NaN }
console.log(test(null));        //-> { parseFloat: NaN, Number: 0 }
console.log(test('true'));      //-> { parseFloat: NaN, Number: NaN }
console.log(test(true));        //-> { parseFloat: NaN, Number: 1 }
console.log(test('false'));     //-> { parseFloat: NaN, Number: NaN }
console.log(test(false));       //-> { parseFloat: NaN, Number: 0 }

parseInt(str)とMath.trunc(str)

  • 共に整数値に変換。
  • 共に四捨五入しない。
  • parseIntは数字以外の文字まで変換するが、truncはNaNを返す。
  • parseIntは2進数や指数表現は変換できない。
  • truncはBigInt形式を変換でもnを文字として認識し変換しない。
  • parseIntの方が約3倍速い。
  • parseIntの絶対値は\(10^{21}\)以下。
  • parseIntは\(2^{32}\)以上必要とする誤差は無視される。
function test(str){
  return {parseInt: parseInt(str), trunc: Math.trunc(str)};
} 
console.log(test('-0.000000001'));      //-> { parseInt: -0, trunc: -0 }
console.log(test('2.9'));               //-> { parseInt: 2, trunc: 2 }
console.log(test(Math.round('2.5',0))); //-> { parseInt: 3, trunc: 3 }
console.log(test(Math.round('2.4',0))); //-> { parseInt: 2, trunc: 2 }
console.log(test('32bit'));             //-> { parseInt: 32, trunc: NaN }
console.log(test('2e+3'));              //-> { parseInt: 2, trunc: 2000 }
console.log(test('2n'));                //-> { parseInt: 2, trunc: NaN }
console.log(test('0xff'));              //-> { parseInt: 255, trunc: 255 }
console.log(test('ff'));                //-> { parseInt: NaN, trunc: NaN }
console.log(test('0b1010'));            //-> { parseInt: 0, trunc: 10 }
console.log(test('0b10_10'));           //-> { parseInt: 0, trunc: NaN }
console.log(test('ichiri'));            //-> { parseInt: NaN, trunc: NaN }
console.log(test('-001.23'));           //-> { parseInt: -1, trunc: -1 }
console.log(test('undefined'));         //-> { parseInt: NaN, trunc: NaN }
console.log(test(undefined));           //-> { parseInt: NaN, trunc: NaN }
console.log(test('NaN'));               //-> { parseInt: NaN, trunc: NaN }
console.log(test(NaN));                 //-> { parseInt: NaN, trunc: NaN }
console.log(test('Infinity'));          //-> { parseInt: NaN, trunc: Infinity }
console.log(test(Infinity));            //-> { parseInt: NaN, trunc: Infinity }
console.log(test('null'));              //-> { parseInt: NaN, trunc: NaN }
console.log(test(null));                //-> { parseInt: NaN, trunc: 0 }
console.log(test('true'));              //-> { parseInt: NaN, trunc: NaN }
console.log(test(true));                //-> { parseInt: NaN, trunc: 1 }
console.log(test('false'));             //-> { parseInt: NaN, trunc: NaN }
console.log(test(false));               //-> { parseInt: NaN, trunc: 0 }
NaN

NaNはNot a Numberだが実はnumber型

console.log(typeof NaN); //->number

NaNを調べる時はisNaNを使う

  • ==や===で調べてのfalseになる。
console.log(NaN==NaN);   //-> false
console.log(NaN===NaN);  //-> false
console.log(isNaN(NaN)); //-> true

NaNは表現できない数字の時使われる

console.log(0/0);            //-> NaN
console.log(parseInt('ichiri'));  //-> NaN
console.log(Math.sqrt(-1));       //-> NaN
console.log(1/0);                 //-> Infinity
Infinity, +0, -0

Infinity 正の無限大

console.log(3*Number.MAX_VALUE);   //-> Infinity
console.log(1/0);                       //-> Infinity
console.log(-1/0);                      //-> -Infinity
console.log(1/Infinity);                //-> 0
console.log(0*Infinity);                //-> NaN
console.log(Infinity/Number.MAX_VALUE); //-> Infinity
console.log(typeof Infinity);           //-> number
console.log(isFinite(Infinity));        //-> false
console.log(Number.POSITIVE_INFINITY);  //-> Infinity
console.log(Number.NEGATIVE_INFINITY);  //-> -Infinity

+0,-0

console.log(+0 === -0); //-> true
文字列、数値の自動変換

文字列や数値を数式内で使うと変換して理にかなっている場合は自動的に変換する。

  • 数字の文字列に数字を*.**./,-等すると文字列を数字に変換する。
  • 例外で数字の文字列に数字を足すだけの場合は文字列の連結になる。
console.log('123.1' * 10);   //-> 1231
console.log('123.1' + 10);        //-> '123.110'
console.log(10 + '123.1');        //-> '10123.1'
console.log(10 + '123.1' +2.0);   //-> '10123.12'
console.log(10 + '123.1' -2);     //-> 10121.1
console.log(Math.sqrt('123.1'));  //-> 11.095043938624128
console.log(Math.log10('123.1')); //-> 2.090258052931316
console.log(Math.cos('123.1'));   //-> -0.8376190239924293
数値の確認

isFinityを使う

  • 指数表現、16進、2進、数字の文字列もtrueになる。
  • 数字でない文字が入っていたらfalseになる。
  • NaN,Infinity,undefinedはfalseになる。
  • nullはtrueになるので追加確認必要。
console.log(isFinite(123.45));      //-> true
console.log(isFinite(.45));         //-> true
console.log(isFinite(-.45));        //-> true
console.log(isFinite(1.23e-4));     //-> true
console.log(isFinite('1.23e-4'));   //-> true
console.log(isFinite(0xff));        //-> true
console.log(isFinite(0b0110_0111)); //-> true
console.log(isFinite(-0));          //-> true
console.log(isFinite('123'));       //-> true
console.log(isFinite('123a'));      //-> false
console.log(isFinite(NaN));         //-> false
console.log(isFinite(Infinity));    //-> false
console.log(isFinite(undefined));   //-> false
console.log(isFinite(null));        //-> true
console.log(null===null);           //-> true
console.log(null*1e+30);            //-> 0
console.log(null==0);               //-> false
isFinite()でチェックして後はnullのチェックだけしたら簡単に数値チェックができますね。
function isNum(num){
  return (isFinite(num) && !(num==null));
}
console.log(isNum(undefined)); //-> false
console.log(isNum(null));      //-> false
console.log(isNum(NaN));       //-> false
console.log(isNum(1.23));       //-> true
console.log(isNum(-123e-4));   //-> true
console.log(isNum('-123e-4')); //-> true
console.log(isNum('ichiri'));  //-> false
四捨五入、切り上げ、切り下げRound,ceil,floorは全て整数を返し すので小数点以下の桁指定の四捨五入、切り上げ、切り下げの時は関数を作るしかない。
function round_u_d(num, digit = 0, round='r'){
  cal_value = 10**(digit);
  switch (round){
    case 'r':
      return (Math.round(num*cal_value))/cal_value;
    case 'd':
      return (Math.floor(num*cal_value))/cal_value;
    case 'u':
      return (Math.ceil(num*cal_value))/cal_value;
    default:
      return `${round} can't be used.  Use r, d or u.`;
  }
}
console.log(round_u_d(123.4567,2));            //-> 123.46
console.log(round_u_d(123.4567,2, 'd'));       //-> 123.45
console.log(round_u_d(123.4567,-1,'r'));       //-> 120
console.log(round_u_d(123.4567,-1,'u'));       //-> 130
console.log(Math.round(123.46*100)*10**(-2));  //-> 123.46000000000001

おまけ 速度比較

以下のコードをそれぞれ1000,000回実行しました。 環境は外部サーバーでCentOS7, AMD EPYC 7543 32-Core Processor, 3.6GHzで流石に速いですね 。 parseFloatよりNumberの方が速いですね。 Math.truncよりparseIntが速いですね。 因みに、for loop だけを1,000,000回、100,000,000回実施したらそれぞれ2.2us、63.2usかかりました。

【速い】Number < parseFloat

const start = performance.now();
for (let i=0; i<1000000; i++) {
  a=Number('1234567890.1234567890');
}
result =(performance.now()-start).toPrecision(3);
console.log('time:', result,'ms'); //-> time: 16.308 ms
const start = performance.now();
for (let i=0; i<1000000; i++) {
  a=parseFloat('1234567890.1234567890');
}
result =(performance.now()-start).toPrecision(3);
console.log('time:', result,'ms'); //-> time: 112.43 ms

Math.trunc > parseInt【速い】

const start = performance.now();
for (let i=0; i<1000000; i++) {
  a=Math.trunc('1234567890.1234567890');
}
result =(performance.now()-start).toPrecision(3);
console.log('time:', result,'ms'); //-> time: 114.51ms
const start = performance.now();
for (let i=0; i<1000000; i++) {
  a=parseInt('1234567890.1234567890');
}
result =(performance.now()-start).toPrecision(3);
console.log('time:', result,'ms'); //-> time: 47.565 ms

コメント