blog

JavaScriptによる強制型変換

JavaScript は動的型付け言語です。 変数には型の制限がなく、いつでも任意の値を代入することができます。 しかし、データ型を必要とするさまざまな演算子があります。演算子の型が期待されたものでな...

Sep 16, 2020 · 6 min. read
シェア

中抜き

JavaScriptは動的型付け言語であり、変数には型の制約がなく、いつでも任意の値を代入することができます。

js
var a = b ? 123 : '123';

しかし、さまざまな演算子にはデータ型に対する要求があります。もし演算子のデータ型が期待されたものでない場合、演算子は自動的にデータ型を変換します。

例えば、減算演算子は左辺と右辺のオペロンが数値であることを期待し、数値でない場合は自動的に数値に変換されます:

js
'5' - '3' // 2

JavaScriptではこれらは強制型変換と総称されることが多く、個人的には暗黙的な強制型変換と明示的な強制型変換を区別する方が好きです。

明示的に強制された型変換はコードから比較的簡単に見分けがつきますが、暗黙的に強制された型変換はあまり目立ちません。

抽象値演算

強制型変換を理解する前に、文字列、数値、ブーリアン値間の型変換の基本ルールを把握する必要があります。

ToPrimitive

抽象操作 ToPrimitive は、オブジェクトから他の型への強制的な型変換を処理します。変換の手順は以下の通りです:

  1. まず、値に valueOf() メソッドがあるかどうかを調べます。
  2. もし型があり、元の型値が返されるなら、その戻り値を強制的な型変換に使います。
  3. もしそうでなければ、toString()メソッドをチェックし、2`の操作を繰り返します。
  4. valueOf() も toString() も基本型の値を返さない場合は、 TypeError エラーがスローされます。

ToString

抽象操作ToStringは、非文字列から文字列への強制型変換を行います:

  1. 元の型の値
  • 数値:対応する文字列に変換します。
  • 文字列:変換後の元の値。
  • Boolean:trueを文字列 "true "に、falseを文字列 "false "に。
  • undefined: "undefined "という文字列に。
  • null: 文字列 "null" に。

非常に小さい値や非常に大きい値を文字列に変換する場合は、指数形式を使用します。

js
String(0x7b); String('abc'); String(!false); String(undefined); String(null); var foo = 1.07 * 0x3e8 * 0x3e8 * 0x3e8 * 0x3e8 * 0x3e8 * 0x3e8 * 0x3e8; foo.toString();
  1. ボーイフレンド

    1. オブジェクト自身の toString メソッドが最初に呼び出されます。元の型の値が返された場合は、その値を ToString します。

    2. そうでない場合は、オブジェクトはToPrimitiveになり、次に戻り値をToStringにします。

    js
    [].toString(); var c = {}; c.toString();

ToNumber

非数値から数値への強制的な型変換を扱う抽象操作ToNumberには、以下の変換規則があります:

  1. 元の型の値
  • 数値:変換後の元の値。
  • 文字列:数値としてパース可能な場合は、対応する数値に変換され、そうでない場合は NaN が返されます。
  • ブール値:trueは1、falseは0になります。
  • undefined:NaNに変換。
  • null:0に変換されます。
js
Number(0x144); Number('324'); Number('324abc'); Number(''); Number(!false); Number(false); Number(undefined); Number(null);

parseInt

parseInt は文字をひとつずつ解析し、文字列内の値を返します。

文字列の最初の要素が数値でない場合、解析結果は NaN を返します。

js
parseInt('123bb456'); parseInt('aa123bb456');
  1. ボーイフレンド

    ToNumberは、最初にオブジェクトに対して ToPrimitive オペレーションを実行した後、戻り値に対して実行されます

ToBoolean

JavaScriptの偽の値はfalseに変換され、偽でない値はtrueに変換されます。 偽の値も含まれます:

  • undefined
  • null
  • false
  • +0、-0、NaN
  • ""

強制型変換の表示

文字列、数値、およびブール値への強制変換を示すメソッドは、それぞれ String() および Number() 、Boolean() およびその他のメソッドです。

暗黙の強制型変換

暗黙の強制型変換は主に以下のような場面で起こります:

  1. 異なる、または同じタイプのデータ同士が互いに作用します。
  2. 非ブール型データ型のブール値
  3. 数値型以外の値には単項演算子を使用します。
  4. 太っ腹
  5. 抽象的関係の比較

データ処理

演算子を文字列に変換する可能性がある加算演算子を除いて、他の演算子は自動的に演算子を値に変換します。

js
'5' - '2'; '5' * '2'; !false - 0x1; false - 0x1; '1' - 0x1; '5' * []; false / '5'; 'abc' - 0x1; null + 0x1; undefined + 0x1;

のオペランドの1つが文字列の場合は文字列の連結を行い、それ以外の場合は数値の加算を行います。

のオペランドの1つがオブジェクトの場合、ToPrimitive抽象化操作が最初に呼び出されます。

js
'12' + 34 // '1234' 34 + '56' // '3456' [] + 34 // '34' {} + 34 // 34

ブーリアン

  • if文の条件判断式。
  • for文の条件判定式。
  • while と do...while(...) ループ
  • ? の条件判断式 :.
  • 論理演算子 || と && の左側のオペランド。

の場合、条件が真の場合は最初のオペランドの値を返し、偽の場合は 2 番目のオペランドの値を返します。

&&はその逆で、条件が真の場合は2番目のオペランドの値を返し、偽の場合は1番目のオペランドの値を返します。

単項演算子

単項演算子も数値に変換します。

js
+'abc' - 'abc' + !false - false;

太っ腹

緩やかな等式===と厳密な等式===の両方が、2つの値が「等しい」かどうかを判断するために使用されますが、両者には重要な違いがあります:===は等式比較で強制的な型変換を許可しますが、===は許可しません

文字列と数値の等価比較

x == y を比較する場合は、値を統一してから再度比較します。

  • Type(x) が数値で Type(y) が文字列の場合、 x == ToNumber(y) を返します。
  • Type(x) が文字列で Type(y) が数値の場合、ToNumber(x) == y を返します。

他の型とブール型の等価比較

x == y を比較する場合、ブール値は数値に変換され、再度比較が実行されます。

  • Type(x) が真偽値の場合、ToNumber(x) == y という結果を返します;
  • Type(y) が真偽値の場合、x == ToNumber(y) を返します。

nullとundefinedの等価比較

ではnullとundefinedは等価ですが、他の値ではそうではありません。

js
null == undefined; null == '123'; undefined == '123'; undefined != null;

個人的には、このようにnullとundefinedを同じ値として扱う方が良いと思います。

オブジェクトと非オブジェクトの等価比較

x == y を比較する場合は、オブジェクトを ToPrimitive にして再度比較します。

抽象的関係の比較

a <= bはb < aとして扱われ、結果は逆になります。

  • 比較の両側はまずToPrimitiveを呼び出し、その結果が文字列でないように見える場合は、ToNumberルールに従って両方の必須型を数値に変換して比較を実行します。
js
var c = [0x2b]; var foo = .42; c & lt; foo; foo & lt; c;
  • 比較の両側が文字列の場合、比較はアルファベット順に行われます。
js
var obj = .42; var c = .043; obj & lt; c;
Read next

フェイントプラクティス -> ソースコード

FeignはNetflixによって開発された軽量なRESTful HTTPサービスクライアントで、vaのようにHTTPリクエストファイルをカプセル化して直接HTTPリクエストを呼び出すのではなく、va接続アノテーションを使用してHTTPリクエストを呼び出します。 同様に...

Sep 16, 2020 · 6 min read