公開後追記
「JS 文字列 存在確認」 とかで検索すると indexOf()
を使う方法がたくさん紹介されてますが、もっといい方法がありました。
@ttatsf さんよりコメントで
可能なら、String.prototype.includes() を使ったらいいですね。
というご指摘をいただきました。
"abcdefg".includes("abc") // true
単純な文字列の有無、存在するかどうかを知りたいときには String.includes()
を使う方が、より明確であり適切。
追記おしまい
ちょっとした罠
気軽に文字列検索したいとき、正規表現使ったりするほどでもないなというとき、indexOf()を使いたい。
ただそんなとき、
Var string = "abcdefg";
if( string.indexOf('abc') ){
// true
console.log('true')
}else{
// false
console.log("false")
}
みたいに書いたとしたら
false
とでてくる。
なんでfalseになるのか?
これはindexOfの返り値は「True/False ではなく ヒットした文字列の出現位置」であり、なおかつ「1文字目は0番目」という仕様が関係している。
つまり、「0番目にヒットした」という意味で string.indexOf('abc')
の返り値は 0
となり暗黙変換によって 0 = false
として処理されることによる。。
厳密にfalseを取るためには、マッチしなかったときの返り値である -1 と比較してあげないといけない。
Var string = "abcdefg";
if( string.indexOf("abc") !== -1 ){
// true
console.log("true");
}else{
// false
console.log("false");
}
こうしてあげると正常。
決して条件式をそのまま突っ込んではいけない。
ビット反転演算子 ~
を使うケース
たまにビット否定演算子 ~
を使って
Var string = "abcdefg";
if( ~string.indexOf("abc") ){
// true
console.log("true");
}else{
// false
console.log("false");
}
としているソースコードがあるが、これは見落としたり直感的・一般的ではないと思うのでよっぽど軽量コーディングを心がけているチームでなければ導入しないほうが無難だと思う。
ちなみにこれが成立する理由は
任意の数値 x のビットごとの NOT 演算は、-(x + 1) を出力します。例えば、~5 で -6 を出力します。
とある通り。つまり以下のような変換を行なっていることになる。
~( -1) => 0 // 暗黙変換によりfalse
~ 2 => -3 // 暗黙変換によりtrue
これはjsにおける「数値において0はfalse、0以外はtrueとする暗黙型変換」を利用したものだが、実質的には T/F で判定しているわけではないため、筆者はちょっと不安を覚えてしまう。
余談にはなりますが、ビット変換がなぜ1ずれるのかは2進数の性質上「正の数の最小値は0」であり、「負の数の最小値が-1」というのが理由。
気になる人は、符号付の2進数について調べてみると良いと思います。