JavaScriptに関するお知らせ

SINCE2019
>
【JS】includes()の使い方に注意、書く順番を間違えやすい原因について

【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はこちらの記事で詳しく紹介してるわよ。



PREV
2019-09-21
WordPressが嫌でNuxt.js+Contentfulでブログを作ったけどHugoに移行した話-後編

NEXT
2019-10-05
【JS】JavaScriptのバッククォートとカリー化の相性良すぎ問題