JavaScriptにおける暗黙的な型変換について

この記事を書いたチーム:frontier

はじめに

【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc.  詳細はこちらから>

JavaScriptでは、他の言語であればクラッシュやエラーが発生するようなコードでも、例外を投げずに処理され、有効な結果を返すケースが多くあります。例えば:

ゼロ除算?無限大。文字列同士で行う引き算の結果?数値ではない!
後者に関しては、あながち間違いとも言えないが…普通はエラーになっていますよね。 

JavaScriptをここまで頑丈(?)にするためには、設計者たちはさまざまな選択を行いました。そしてその結果、生まれた副作用(直感に反する挙動)も少なくありません。

加算演算子

次の式の結果はなんでしょう?

ほとんどの言語では空配列、もしくは型エラーのどちらかになりますが、JavaScriptで実行すると予想外の結果になります:

空文字列です。初めてこの挙動を目にする方であれば、さぞ驚かれることでしょう。

ここでJavaScriptの加算演算子 (+) の動作について、少し説明させていただきます。他の多くの言語と同様に、JavaScriptの+演算子は数値の加算と文字列の連結という2つの役割を持っています。具体的な動作は以下の通り:

まず、両方のオペランドが数値の場合は、期待通りの数値の加算が行われます。

オペランドが数値でなくても、数値に変換可能なものであれば、それらを自動的に数値に変換して加算します。

数値に変換できない場合、オペランドを文字列に変換してから連結します。

配列は直接数値に変換することができないので、文字列にされたのです。

等価演算子

JavaScriptでは、次の比較がtrueに当たります。

論理値のコンテキストに現れた時に、真(true)として扱われるものを真値(truthy)、偽(false)として扱われるものを偽値(falsy)と呼びます。

JavaScriptでは偽値として定義されている値は下記の6つのみ:

  1. false
  2. 0
  3. “”
  4. null
  5. undefined
  6. NaN

そして、それ以外の値はすべて真値であります。

JavaScriptの等価演算子(==)は緩い等価性を評価する――オペランドの型が異なる場合、同じ型になるように型変換を試みてから比較を行います:

片方のオペランドがオブジェクトでもう片方がプリミティブである場合、オブジェクトのオペランドをプリミティブに変換します。

片方のオペランドが論理値でもう片方がそうでない場合、論理値から数値に変換します。

オペランドが数値と文字列の場合、文字列のオペランドを数値に変換します。

値を比較する際に意図しない結果にならないように、原則として厳密等価演算子(===)を使うようにしましょう。

おわりに

以下のコードは有効なJavaScriptです。

実行したらどのような結果になるのでしょうか?

【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>

Smallitのサービス