JavaScriptで文字列の有無を調べるにはindexOfではなくtestを使う

JavaScriptで文字列の有無を調べるにはindexOfではなくtestを使う

indexOfではなくtestメソッドを使う

JavaScriptで文字列の有無を調べる際にindexOfが使用されているコードをよく見かける。

indexOfを使用すれば以下のように文字列の有無を調べることができる。

indexOfは指定した文字列が含まれている場合は初めて出現したインデックス。見つからなかった場合は-1を返す。

var str = 'This is a apple pen';
if (str.indexOf('apple') !== -1) {
 console.log(true);
} else {
 console.log(false);
}
// => true

indexOfは正規表現が使用できないため文字列の有無を調べるなら正規表現が使用できるtestメソッドを使用したほうが良い。

例えばappleまたはbananaも含まれているかどうかをindexOfで調べるにはこのような書き方になる。

var str = 'This is a apple pen';
if (str.indexOf('apple') !== -1 || str.indexOf('banana') !== -1) {
 console.log(true);
} else {
 console.log(false);
}
// => true

これをtestメソッドで書いた場合、以下のように簡潔に書ける。

var str = 'This is a apple pen';
if (/apple|banana/.test(str)) {
 console.log(true);
} else {
 console.log(false);
}
// => true

見ての通りtestメソッドなら|で区切って文字列を追加すれば良いがindexOfだと記述が多いためコードの可読性が悪くなってしまう。

また、appleは含めるがapple penは含んでいない文字列を調べる際もtestメソッドのほうが簡潔に書ける。

var str = 'This is a apple pen';
if (str.indexOf('apple') !== -1 && str.indexOf('apple pen') === -1) {
 console.log(true);
} else {
 console.log(false);
}
// => false

if (/apple(?! pen)/.test(str)) {
 console.log(true);
} else {
 console.log(false);
}
// => false

正規表現を使用せず、マッチが1つだけであればindexOfを使用したほうがtestよりも処理が速いがマッチが複数であればtestのほうが処理が速く、正規表現が使用でき可読性も高い。

正規表現を使用せず、マッチが1つだけでもindexOfとtestの処理速度に大きな差はないので通常のWebサイトであればすべてtestで記述しても問題ない。

また、indexOfは大文字・小文字を必ず区別するがtestならiオプションを追加することで大文字と小文字を区別しないこともできる。

/Hello/.test('hello');
// => false

/Hello/i.test('hello');
// => true

文字列の有無にmatchメソッドを使用しない

文字列の有無にmatchメソッドを使用しているケースもよく見かけるがmatchは本来全てのマッチを含む配列及び括弧内で捕獲された結果の配列を返すときに使用するものなので文字列の有無を確認するだけならtestメソッドを使用したほうが良い。

var str = 'This is a apple pen';
if (str.match(/apple/)) {
 console.log(str.match(/apple/));
 console.log(true);
} else {
 console.log(false);
}
// => ["apple", index: 10, input: "This is a apple pen"]
// => true

あとsearchメソッドを使用しているケースも見かけるが、これもindexOfと同様に文字列内でマッチした箇所のインデックスを返し、マッチしなかった場合は -1 を返すので文字列の有無を確認するだけならtestメソッドを使用したほうが良い。

var str = 'This is a apple pen';
if (str.search(/apple/) !== -1) {
 console.log(str.search(/apple/));
 console.log(true);
} else {
 console.log(false);
}
// => 10
// => true

indexOfは配列内の文字列の有無を調べる

indexOfは配列要素で指定した文字列の最初の添字を返すことができるため配列に使用すると良い。存在しない場合は -1 を返します。

var arr = ['apple', 'banana'];
if (arr.indexOf('banana') !== -1) {
 console.log(true);
} else {
 console.log(false);
}
// => true

!== -1ではなくチルダ演算子(~)を使用すると短く書ける。

var arr = ['apple', 'banana'];
if (~arr.indexOf('banana')) {
 console.log(true);
} else {
 console.log(false);
}
// => true

ちなみにincludesという特定の要素が配列に含まれているかどうかをtrueかfalseで返すメソッドもあるのだがIEとMicrosoft Edgeで使用できないためWebサイトで使用されているケースは少ない。

var arr = ['apple', 'banana'];
if (arr.includes('banana')) {
 console.log(true);
} else {
 console.log(false);
}
// => true

indexOfとtestメソッドを使用したサンプル