【JS】includes()の使い方に注意、書く順番を間違えやすい原因について
こんにちは!今日はJavaScriptで配列検索するincludesはケアレスミスしやすいって話です。
includesが登場するまで
一昔前
昔はindexOfを使っていましたねー、まだIEが闊歩していた時代です。
indexOfの解説は星の数ほどあるので省略。ショートハンド使うとこんな感じに書けました。
!!~[1, 2, 3].indexOf(1) // true
!!~[1, 2, 3].indexOf(4) // false
ちょっとわかりにくいね。解説すると解説しないんじゃないの?
- indexOfは含まないと-1になる
- チルダは *1 したあと -1 する
- -1 はチルダ付けると 0 になる
- JavaScriptの数字は0だけfalsy(falseとみなされる)
- ! はtruthyとfalsyと反転させbool型にする
- なので !! はtruthyとfalsyをtrueとfalseにする(反転したあとまた反転している)
- !! でfalseになる数字はfalsy、つまり 0 だけ
- !! ~ で-1 だけfalseになる
みたいな感じ。分かっちゃえばだけど、でもやっぱ書くのめんどい。
現在
includes()ができて、上みたいなコード書かなくてもよくなりました。こう。
;[1, 2, 3]
.includes(1) // true
[(1, 2, 3)].includes(4) // false
めっちゃわかりやすいね。もうincludesだけでいいんじゃないかな? と私は思っていました。しかし…
includes()の間違えやすさ
includesを使う時
皆さんは次のコードを脳内で解釈する時どうします?
;[1, 2, 3].includes(1)
[1, 2, 3]は1を含んでいるか? って思いますよね?
でも!でもですよ。上のようなコードが出てくる時って、大抵調べたいのは
**[1, 2, 3]の中に1はあるか?**ですよね。この場合って、
**普通は探す方の1に着目しません?**もっと言えば、1に相当する部分ってよく変数になってたりしない?
一般論として、何かと何かと比較する際にはミュータブルが左辺に来るはずです。if(num > 42) みたいな条件分岐のコード、みたことあると思いますが**if(42 < num)**とかあんまないんじゃないでしょうか。
結果的にincludesでやりがちなミス
ミュータブルが左辺みたいな意識を持っていると、このようなミスが往々にして起こります。
1.includes([1, 2, 3]) //SyntaxError
まだ配列の場合はいいです、シンタックスエラーが出るので。じゃあ文字列ならどうよ。
'31415926535'.includes('1')
'1'.includes('31415926535')
これ殆どの人がどっちが正しいか一瞬でわかんないと思う。
しかも、正解はtrueなのに間違ってる方はfalseが返る上にErrorも出ない。危険。
ちなみに正解は上。探す対象の’1’が後に来ています…
なぜ間違えやすいのか
おそらくだけど includes(含む)とbe included in (含まれる)が非ネイティブに直感的に理解できないのが原因だと思う。
自動詞と他動詞な。他にもsurpriseとかinterestingとかが間違えやすいぞ(受験生並の感想)
including tax(税込み) と tax included(税込み) とかが好例ですね。
対策
ネイティブになる
Sincerely,
余談
matchとかsearch使う方法もあるけど、結局戻り地がboolじゃないんで !! とか !! ~ 使わんといかんくなる。そしてこれ書くの忘れる。
matchやsearchはこちらの記事で詳しく紹介してるわよ。