JavaScriptで特定の要素が含まれているかを判定する際、includesメソッドは最も直感的で便利な手段の一つです。
かつてはindexOfメソッドを使用して、戻り値が-1より大きいかどうかを確認するという回りくどい記述が必要でした。
しかし、includesメソッドの登場により、コードの可読性は飛躍的に向上し、プログラミングの意図が明確に伝わるようになりました。
本記事では、文字列および配列におけるincludesメソッドの基本的な使い方から、実戦で役立つ高度な活用法までを解説します。
JavaScriptのincludesメソッドとは
includesメソッドは、文字列や配列の中に特定の要素が含まれているかどうかを真偽値(trueまたはfalse)で返すメソッドです。
このメソッドは、ES2016(ES7)で導入され、現在ではモダンなフロントエンド開発において欠かせない標準機能となっています。
従来の手法と比較して、戻り値が数値ではなく論理値であるため、条件分岐(if文)などでそのまま利用できるのが大きなメリットです。
プログラムの意図が「値が含まれているか」という単純な問いである場合、このメソッドを使うことがベストプラクティスとされています。
まずは、includesメソッドの基本的な構文を確認しておきましょう。
// 文字列の場合の構文
string.includes(searchString, position);
// 配列の場合の構文
array.includes(valueToFind, fromIndex);
いずれの場合も、第1引数に「探したい要素」を指定し、第2引数に「検索を開始する位置」を指定します。
第2引数は省略可能であり、省略した場合は先頭から検索が開始されます。
文字列でのincludesメソッドの使い方
文字列におけるincludesメソッドは、特定の「部分文字列」が存在するかどうかを判定します。
ウェブアプリケーションにおいて、ユーザー入力のバリデーションや、URLの中に特定のパラメータが含まれているかを確認する際によく使われます。
基本的な文字列検索
最もシンプルな使い方は、検索対象となる文字列を引数に渡す方法です。
const message = "JavaScriptプログラミングを楽しもう";
const result = message.includes("プログラミング");
console.log(result);
true
このように、指定したキーワードが含まれていればtrueが返り、含まれていなければfalseが返ります。
大文字と小文字の区別に注意
includesメソッドを使用する際に最も注意すべき点は、大文字と小文字を厳密に区別するという仕様です。
たとえば、「JS」と「js」は異なる文字列として扱われます。
const tech = "JavaScript";
console.log(tech.includes("java")); // 全て小文字なのでfalse
console.log(tech.includes("Java")); // 先頭が大文字なのでtrue
false
true
実務において、検索ワードの表記揺れを許容したい場合は、検索対象とキーワードの両方をtoLowerCase()メソッドで小文字に変換してから比較するのが一般的です。
const original = "JavaScript";
const searchWord = "JAVA";
// 両方を小文字にして比較する
const isMatch = original.toLowerCase().includes(searchWord.toLowerCase());
console.log(isMatch);
true
検索開始位置の指定
第2引数を利用することで、文字列の特定のインデックスから検索を開始することができます。
これにより、文字列の冒頭部分は無視して、後半部分だけをチェックするといった処理が可能になります。
const text = "apple, banana, cherry";
console.log(text.includes("apple", 0)); // 0番目から探すのでtrue
console.log(text.includes("apple", 1)); // 1番目から探すと"apple"は見つからないのでfalse
true
false
配列でのincludesメソッドの使い方
配列におけるincludesメソッドは、配列内に特定の要素が含まれているかを確認するために使用されます。
こちらも文字列と同様に非常にシンプルなコードで記述できます。
基本的な配列検索
数値や文字列の配列に対して使用する場合の例を見てみましょう。
const fruits = ["apple", "banana", "orange"];
if (fruits.includes("banana")) {
console.log("バナナが含まれています。");
}
バナナが含まれています。
以前のJavaScriptでは、fruits.indexOf("banana") !== -1と書く必要がありました。
しかし、includesを使うことで、一目で条件分岐の内容が理解できるクリーンなコードになります。
厳密等価判定(===)による比較
includesメソッドは、内部的に厳密等価(===)に近いアルゴリズムで比較を行います。
そのため、データ型が異なる場合は一致しないと判定される点に注意が必要です。
const numbers = [10, 20, 30];
console.log(numbers.includes(10)); // 数値の10なのでtrue
console.log(numbers.includes("10")); // 文字列の"10"なのでfalse
true
false
NaNの判定が可能
includesメソッドがindexOfメソッドよりも優れている点の一つに、NaN(Not-a-Number)を正しく判定できるという特徴があります。
通常、JavaScriptにおいてNaN === NaNはfalseになりますが、includesは特別にNaNの存在を検知できます。
const list = [1, 2, NaN];
console.log(list.indexOf(NaN)); // -1 を返す(見つけられない)
console.log(list.includes(NaN)); // true を返す(見つけられる)
-1
true
計算結果にエラーが含まれていないかを確認するようなロジックでは、includesの方が安全です。
オブジェクトを含む配列での注意点
初心者の方が最も陥りやすい罠が、オブジェクトや配列を要素に持つ配列に対するincludesの使用です。
結論から言うと、オブジェクトのプロパティ値が同じであっても、参照が異なればincludesはfalseを返します。
参照の一致が必要なケース
以下の例を見て、なぜ期待通りに動作しないのかを確認してください。
const users = [{ name: "田中" }, { name: "佐藤" }];
// 同じ内容のオブジェクトを引数に渡すが、参照が異なる
console.log(users.includes({ name: "田中" }));
false
変数に代入された同じインスタンスを検索する場合は、trueが返ります。
const tanaka = { name: "田中" };
const users = [tanaka, { name: "佐藤" }];
console.log(users.includes(tanaka));
true
このように、オブジェクトの「中身」を基準に検索したい場合は、includesではなくsomeメソッドやfindメソッドを使用するのが適切です。
includesメソッドと他メソッドの比較
要素の有無を判定する方法は他にもあります。
状況に応じて最適なメソッドを選択するために、主要なメソッドとの違いを表にまとめました。
| メソッド名 | 主な戻り値 | 主な用途 | NaNの判定 |
|---|---|---|---|
includes() | true / false | 存在確認(シンプル、可読性重視) | 可能 |
indexOf() | インデックス / -1 | 位置を特定したい場合 | 不可 |
some() | true / false | 複雑な条件(オブジェクトの内容など)での検索 | 可能 |
find() | 要素そのもの / undefined | 条件に合う最初の要素を取得したい場合 | 可能 |
基本的には、「単純な値があるかどうかを知りたいだけ」であれば、includesを使うのが最も簡潔なコードになります。
includesメソッドの応用パターン
ここからは、実務でよく使われるincludesの応用的なテクニックを紹介します。
複数の条件を簡潔に記述する
例えば、ある変数が「AまたはBまたはC」のいずれかに該当するかをチェックしたい場合、論理演算子(||)を使うとコードが長くなりがちです。
includesを活用すれば、条件を配列にまとめてスマートに記述できます。
const role = "admin";
// 冗長な書き方
if (role === "admin" || role === "editor" || role === "manager") {
// 処理
}
// includesを使ったスマートな書き方
const allowedRoles = ["admin", "editor", "manager"];
if (allowedRoles.includes(role)) {
console.log("アクセスが許可されました。");
}
アクセスが許可されました。
このパターンは、許可された拡張子のチェックや、ユーザー権限の確認などで非常に役立ちます。
空配列やundefinedのハンドリング
includesメソッドを呼び出す対象がnullやundefinedである場合、JavaScriptはエラー(TypeError)をスローします。
安全に判定を行うためには、オプショナルチェイニング(?.)を併用するのが現代的な書き方です。
const data = null;
// エラーを防ぎつつ安全に確認する
const hasItem = data?.includes("target") ?? false;
console.log(hasItem);
false
パフォーマンスに関する考察
includesメソッドは、配列の先頭から順番に要素を調べていく「線形探索」というアルゴリズムを採用しています。
そのため、配列の要素数が数万件、数十万件と膨大になる場合、検索効率が低下する可能性があります。
もし大量のデータに対して頻繁に存在確認を行う必要がある場合は、Setオブジェクトの使用を検討しましょう。
Setオブジェクトのhasメソッドは、ハッシュテーブルを利用するため、データ量に関わらず高速に動作します。
const largeArray = [...Array(1000000).keys()];
const largeSet = new Set(largeArray);
// 配列のincludesは時間がかかる場合がある
console.time("array");
largeArray.includes(999999);
console.timeEnd("array");
// Setのhasは一瞬で終わる
console.time("set");
largeSet.has(999999);
console.timeEnd("set");
一般的なウェブサイトの開発であれば、数十〜数百程度の要素数であることが多いため、基本的にはincludesを使って問題ありません。
「まずは可読性の高いincludesを使い、パフォーマンスがボトルネックになったらSetを検討する」というスタンスが良いでしょう。
よくある質問(FAQ)
Q. includesメソッドは古いブラウザでも動きますか?
A. Internet Explorer(IE)ではサポートされていませんが、現代の主要なブラウザ(Chrome, Edge, Firefox, Safari)ではすべて問題なく動作します。
もし古い環境をサポートする必要がある場合は、Babelなどのトランスパイラを利用するか、ポリフィルを導入してください。
Q. 空の文字列をincludesに渡すとどうなりますか?
A. 文字列のincludesメソッドに空文字列(””)を渡すと、常にtrueが返ります。
これはJavaScriptの仕様に基づいた挙動ですので、実装時には注意が必要です。
console.log("Hello".includes(""));
true
まとめ
JavaScriptのincludesメソッドは、コードをシンプルかつ読みやすくするための強力なツールです。
文字列や配列に対して「要素が存在するか」という問いに直感的に答えを出してくれます。
本記事で解説した以下のポイントを意識して、日々の開発に役立ててください。
- 文字列検索では大文字と小文字が区別されること。
- 配列検索では厳密等価(===)で比較されるため、型の一致が必要であること。
- NaNを正しく判定できるという、indexOfにはない利点があること。
- オブジェクトの配列を検索する場合は、参照の違いに注意すること。
- 条件分岐をスッキリさせたい場合に、配列と組み合わせると効果的であること。
正しい知識を持ってincludesメソッドを活用することで、バグの少ない保守性の高いJavaScriptコードを書けるようになります。
まずは小さな条件分岐から、この便利なメソッドを取り入れてみてはいかがでしょうか。
