この記事は エムスリー Advent Calendar 2022 の 21 日目の記事です。
前日は @mski_iksm による 毎日追加学習する機械学習モデルを、日次実行を止めずにコードをバージョンアップしたい - エムスリーテックブログ でした。
こんにちは。エンジニアリンググループの西川です。
好きな言語は JavaScript です。
適当に書いているので実はあまり習熟していないです。
さて、私は趣味で JavaScript のことを頻繁に調べているのですが、この言語は「好き」と打つと「好きになれない」がサジェストに出てきます。
私はこのことを大変心苦しく思っていました。
JavaScript は思い立ったらすぐ書け、動かせる、非常に魅力的な言語です。今この記事を閲覧しているブラウザひとつで、サクッと実行できます。
そんな素晴らしい言語が嫌われることは極めて遺憾であり、やり切れない思いが胸に渦巻くのですが、同時に実際に xxxxx みたいな動きをするし仕方ない部分もあるなと。
そのため、今回は皆さまが苦しめられているであろう JavaScript のひどい挙動と、その対処法をご紹介したいと思います。
- 1. "1" == 1 が true
- 2. parseInt(false, 16) が 250
- 3. 1 + true が 2
- 4. null && false が null
- まとめ
- We are hiring!!
1. "1" == 1
が true
文字列(string)と数値(number)だから false
! と思ったら true
…… 往々にしてあると思います。
この挙動自体は JavaScript としては正しいです。なぜなら、この ==
というイコールが 2 個の式の「等価演算子」では、 一度 型の変換を試みてから比較するためです。
例えば、[] == 0
も true
になります。 []
は文字列に変換すると ""
(空文字)で、数値に変換すると 0
だからです。
しっかり確かめたい場合は ===
の「厳密等価演算子」を利用するようにしましょう。
2. parseInt(false, 16)
が 250
なぜエラーにならないのでしょうね?
JavaScript の parseInt()
関数は、第一引数に与えられた文字列を一度 string に変換した上で、第二引数で与えられた基数で変換できない文字に当たるまで、1 文字目から順に解析して変換した整数値を返すためです。
parseInt("10test", 10)
でも 10
が返ってきたりします。
parseInt()
関数を実施する前に、想定外の文字列が入っていないかチェックを行うか、(状況によっては)Number()
関数を利用した方が良いと思います。
ちなみに、parseInt()
関数の第二引数を与えないと、「よしなに」解釈して変換するため、予想外の挙動を引き起こすことがあります。気をつけましょう。
3. 1 + true
が 2
エラーになってほしいですね。
1〜3 を見てきて薄々お気づきになられたと思いますが、JavaScript は型が明示的に指定されない言語なので、事あるごとに善意で型の変換*1をしてきます。
true
は 1
に変換されるため、1 + 1 = 2
! となっています。
同じように、false
や null
も 0
になってしまったりします。
どのような値になるかは明確に規則があるわけではなさそうなので、値のチェックをしっかりした方が安全です。
4. null && false
が null
false
じゃないのかよと。
JavaScript の論理積(&&
)は左から解釈され、false
に変換できる値(偽値/falsy)に遭遇した際に処理をやめ、今見ている値を返します。
「今見ている値を返す」のは true
の場合でも同じなため、true && 1
だと、最後まで見た上で 1
が返ります。
論理積の結果を boolean として受け取りたい場合は、二重否定演算子(!!
)などを使ってしっかり変換しましょう。
まとめ
いかがでしたか?
これでも this の挙動や、変数のスコープなど、昔と比べるとかなり改善されているので、使いやすくなってきています。
JavaScript のことがわかると、嫌悪感も減ると思います。
JavaScript を書きましょう。
そしてどうか、JavaScript のことを愛してください。
……もう既にかなり愛されてない? (Loved = 61.46%) https://survey.stackoverflow.co/2022/#most-loved-dreaded-and-wanted-language-love-dread
We are hiring!!
エムスリーでは、共にサービス開発をしてくれるメンバーを募集しています。
JavaScript の好き嫌いに関係なく、開発自体が大好きという方はぜひご応募ください!
*1:Type coercion: https://developer.mozilla.org/ja/docs/Glossary/Type_coercion