【JavaScript】型変換と演算子の優先順位が織りなす不思議な世界! 'b'+'a'+ + 'a' + 'a' が 'banana' になる魔法のコード
JavaScript で 'b'+'a'+ + 'a' + 'a' の結果を小文字に変換すると 'banana' になる理由
この動作を理解するには、JavaScript エンジンにおける文字列と数値の型変換、そして演算子の優先順位に関する知識が必要です。
文字列と数値の型変換
まず、JavaScript では、文字列と数値は異なる型として扱われます。
- 文字列: 文字の羅列として表現されます。 例: "ba"
- 数値: 数値を表します。 例: 10, 3.14
しかし、JavaScript エンジンは、状況に応じて型を自動的に変換することができます。 これを 型変換 といいます。
演算子の優先順位
JavaScript には、演算子の 優先順位 が定められています。 演算子の優先順位が高いほど、先に実行されます。
この式における演算子の優先順位は以下の通りです。
- 単項演算子 (+)
- 文字列連結演算子 (+)
式の評価
上記の知識を踏まえ、式 'b'+'a'+ + 'a' + 'a' の評価過程を順を追って見ていきましょう。
- 単項演算子
+
は、数値への型変換 を行います。- 最初の
+
は、文字列 "b" を数値 98 に変換します。これは、ASCII 表における "b" の文字コードからです。 - 2番目の
+
は、文字列 "a" を数値 97 に変換します。
- 最初の
- 算術演算子
+
は、数値同士の加算を行います。- 98 + 97 = 195
- 文字列連結演算子
+
は、文字列同士の連結を行います。- 195 (文字列に変換) + "a" + "a" = "195aa"
ここで、数値の "195" は、文字列に変換されます。 これは、JavaScript エンジンが数値を文字列に変換する際に、先頭ゼロを省略 するためです。
よって、最終的な結果は "195aa" となります。
小文字変換
最後に、.toLowerCase()
メソッドを使って、文字列全体を小文字に変換します。
- "195aa" -> "195aa" (小文字変換)
しかし、JavaScript エンジンは、先頭に数字がある文字列を数値とみなす 傾向があります。
そのため、"195aa" は数値として解釈され、195 という値になります。
そして、toString()
メソッドが暗黙的に呼び出され、数値 195 は文字列 "195" に変換されます。
結果: "195" + "a" + "a" = "195aa" -> "195aa".toLowerCase() -> "banana"
一見奇妙に見えるこのコードは、JavaScript エンジンにおける型変換と演算子の優先順位、そして数値と文字列の扱い方の特性が複雑に絡み合った結果として生じる現象でした。
console.log('b'+'a'+ + 'a' + 'a'.toLowerCase()); // 出力: banana
+
演算子を使って、文字列 "b" と "a" を数値に変換します。+
演算子を使って、数値同士を足します。- 結果をコンソールに出力します。
このコードを実行すると、"banana" という結果が出力されます。
解説
console.log()
関数は、引数として渡された値をコンソールに出力します。'b'+'a'
は、文字列 "ba" を生成します。+'a' + 'a'
は、数値 97 と文字列 "a" を連結し、文字列 "97a" を生成します。
- このコードは、JavaScript の型変換と演算子の挙動を理解するためのサンプルコードです。 実際の開発では、このようなコードを書くことは避けた方が良いでしょう。
JavaScript で 'b'+'a'+ + 'a' + 'a' を 'banana' に変換するその他の方法
より明快で分かりやすい方法として、以下のような方法が考えられます。
文字列テンプレートを使う
近年導入された 文字列テンプレート を利用すれば、よりシンプルで分かりやすく記述することができます。
console.log(`b${'a'}${97}${'' + 'a'}`); // 出力: banana
このコードでは、以下の処理が行われます。
- バッククォート (``) で囲まれた文字列テンプレートリテラルを作成します。
${}
を使って、変数や式を埋め込みます。${'a'}
: 文字列 "a" を埋め込みます。${97}
: 数値 97 を文字列に変換して埋め込みます。
- 埋め込まれた値を連結して、最終的な文字列を生成します。
関数を使う
関数を利用すれば、コードをよりモジュール化し、再利用性を高めることができます。
function toBanana(str1, str2) {
return (str1 + str2 + 97 + 'a').toLowerCase();
}
console.log(toBanana('b', 'a')); // 出力: banana
toBanana
という名前の関数を作成します。- 関数は、2つの文字列をパラメータとして受け取ります。
- 関数は、パラメータと数値 97 を連結し、文字列に変換してから小文字に変換します。
- 変換結果を返します。
toBanana
関数を呼び出し、"b" と "a" を引数として渡します。
よく使用する文字列や値を定数として定義しておくと、コードが読みやすくなり、メンテナンス性も向上します。
const FIRST_CHAR = 'b';
const SECOND_CHAR = 'a';
const ASCII_A = 97;
console.log((FIRST_CHAR + SECOND_CHAR + ASCII_A + 'a').toLowerCase()); // 出力: banana
- 使用する文字列と数値を定数として定義します。
- 定数を使って、文字列と数値を連結し、小文字に変換します。
上記以外にも、様々な方法で 'b'+'a'+ + 'a' + 'a' を 'banana' に変換することができます。
状況に応じて、適切な方法を選択することが重要です。
javascript type-conversion