Catatan pesan pelanggan di toko Siti menumpuk sepanjang hari: “Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.” Dari tumpukan teks seperti itu muncul pertanyaan-pertanyaan yang berulang setiap saat. Adakah kata tertentu di dalamnya? Kata itu berada di posisi berapa? Apakah pesan diawali atau diakhiri teks tertentu? Dan di mana saja sebuah kode pesanan muncul?
JavaScript menyediakan method string untuk setiap bentuk pertanyaan tersebut, dan keempatnya punya bentuk jawaban yang berbeda:
| Pertanyaan | Method | Bentuk jawaban |
|---|---|---|
| Adakah kata “gula”? | includes | true atau false |
| Kata “Tanya” ada di posisi berapa? | indexOf / lastIndexOf | indeks, atau -1 bila tidak ada |
| Apakah teks diawali “Tanya”? | startsWith / endsWith | true atau false |
Di mana saja kode kopi-... muncul? | matchAll | daftar semua kecocokan beserta posisinya |
includes: Ada atau Tidaknya Sebuah Teks #
Aturan includes(teks): kembalikan true bila argumennya ditemukan di dalam string, dan false bila tidak. Argumen kedua bersifat opsional berupa indeks awal pencarian.
const catatan = "Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.";
console.log(catatan.includes("gula"));
console.log(catatan.includes("teh"));
console.log(catatan.includes("Tanya", 10));Output yang Dihasilkan:
true
false
trueBaris ketiga memperlihatkan peran argumen kedua: pencarian dimulai dari indeks 10 sehingga “Tanya” pertama terlewati, tetapi “Tanya” kedua tetap ditemukan dan hasilnya tetap true.
Berikut bukti kepekaan huruf beserta cara menyiasatinya:
const pesan = "Tolong Kirim KOPI";
console.log(pesan.includes("kopi"));
console.log(pesan.toLowerCase().includes("kopi"));Output yang Dihasilkan:
false
trueindexOf dan lastIndexOf: Menemukan Posisi #
indexOf mengembalikan indeks kemunculan pertama; bila tidak ditemukan, kembaliannya -1 — angka yang tidak mungkin menjadi indeks sah. lastIndexOf bekerja sebaliknya: pencarian dimulai dari akhir string dan posisi kemunculan terakhir yang dilaporkan. Sama seperti includes, argumen kedua menetapkan posisi mulai pencarian.
const catatan = "Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.";
console.log(catatan.indexOf("Tanya"));
console.log(catatan.indexOf("teh"));
console.log(catatan.lastIndexOf("Tanya"));
console.log(catatan.indexOf("Tanya", 5));Output yang Dihasilkan:
0
-1
35
17Kata “Tanya” muncul tiga kali di dalam catatan. indexOf melaporkan kemunculan pertama pada indeks 0, lastIndexOf melaporkan yang terakhir pada indeks 35, dan argumen kedua 5 membuat pencarian mulai dari indeks 5 sehingga kemunculan kedua (indeks 17) yang terlaporkan.
Nilai -1 bukan error, melainkan sinyal “tidak ditemukan”. Sifat itulah yang membuat indexOf cocok dipasangkan dengan loop untuk menghitung semua kemunculan sebuah kata:
const catatan = "Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.";
let posisi = catatan.indexOf("Tanya");
let hitungan = 0;
while (posisi !== -1) {
hitungan++;
posisi = catatan.indexOf("Tanya", posisi + 1);
}
console.log(hitungan);Output yang Dihasilkan:
3Mari kita bedah mekanisme loop di atas:
- Baris 2 (
catatan.indexOf("Tanya")): pencarian pertama menemukan kecocokan pada indeks0, dan posisi itu ditampung diposisi. - Baris 4 (
while (posisi !== -1)): loop berjalan selama kecocokan masih ditemukan. - Baris 5 (
hitungan++): setiap putaran mencatat satu kecocokan. - Baris 6 (
catatan.indexOf("Tanya", posisi + 1)): pencarian berikutnya dimulai satu karakter setelah kecocokan terakhir, sehingga posisi yang sama tidak dihitung dua kali. - Baris 8: ketika tidak ada kecocokan lagi,
indexOfmengembalikan-1, kondisi loop bernilaifalse, danhitunganberisi3.
startsWith dan endsWith: Memeriksa Ujung String #
Kedua method menjawab pertanyaan posisi yang lebih khusus: apakah string dimulai atau diakhiri teks tertentu. Pemeriksaan ujung sering dipakai untuk memilah nama berkas, kode, dan awalan pesan.
const namaBerkas = "laporan-penjualan-2026.csv";
console.log(namaBerkas.startsWith("laporan"));
console.log(namaBerkas.endsWith(".csv"));
console.log(namaBerkas.endsWith(".pdf"));
console.log(namaBerkas.startsWith("2026", 18));Output yang Dihasilkan:
true
true
false
trueBaris keempat memakai argumen kedua startsWith sebagai posisi mulai pemeriksaan. Pada nama berkas itu, tahun "2026" tepat berada di indeks 18, sehingga pemeriksaan dari titik itu bernilai true.
matchAll: Semua Kemunculan Sekaligus #
Method sebelumnya berhenti pada satu jawaban. matchAll melangkah lebih jauh: ia mengembalikan seluruh kecocokan sebuah pattern sekaligus, lengkap dengan posisi masing-masing. Pattern ditulis dengan sintaks regex /.../g — dua garis miring membentuk regex object, sedangkan huruf g memerintahkan pencarian semua kemunculan. Keduanya dibedah tuntas di dua chapter berikutnya; untuk saat ini cukup amati hasilnya:
const log = "kopi-101, teh-300, kopi-205, gula-400, kopi-777";
const temuan = [...log.matchAll(/kopi-[0-9]+/g)];
console.log(temuan.length);
for (const hasil of temuan) {
console.log(hasil[0], "di indeks", hasil.index);
}Output yang Dihasilkan:
3
kopi-101 di indeks 0
kopi-205 di indeks 19
kopi-777 di indeks 39Pattern /kopi-[0-9]+/g dapat dibaca: kata “kopi”, tanda hubung, lalu satu atau lebih angka. matchAll mengembalikan iterator, dan tanda kurung siku [...] — spread yang dikenal dari section Objects — mengumpulkannya menjadi array supaya mudah diproses dengan for...of. Setiap elemen hasil adalah object kecocokan: hasil[0] berisi teks yang cocok, sedangkan hasil.index menyimpan posisi kemunculannya.
Memilih Method yang Tepat #
Empat method chapter ini menjawab empat kebutuhan yang berbeda, dan memilih yang salah biasanya membuat kode jadi lebih panjang dari yang seharusnya. Panduan singkatnya:
- Butuh jawaban ya atau tidak? Gunakan
includes— satu pemanggilan, hasil boolean. - Butuh posisi kemunculan, atau perlu menghitung kemunculan dengan loop? Gunakan
indexOfdanlastIndexOf. - Butuh memeriksa awalan atau akhiran, misalnya ekstensi berkas? Gunakan
startsWithdanendsWith. - Butuh semua kecocokan dari sebuah pola? Gunakan
matchAlldengan regex berflagg.
Semua method di atas bekerja pada teks yang ditulis persis atau — untuk matchAll — pattern yang mendeskripsikan bentuk teks. Ketika pencarian mulai berbunyi “temukan angka diikuti huruf” atau “kata yang bisa berupa tiga ejaan berbeda”, waktunya beralih ke regular expression.
Studi Kasus: Menyaring Catatan Pesan Pelanggan #
Berkas berikut merangkum seluruh method chapter ini dalam satu alur kerja: periksa ada-tidaknya kata, temukan posisinya, hitung kemunculannya, lalu ekstrak semua kode pesanan dari log.
// pencarian-pesan.js
// Siti menyaring catatan pesan pelanggan berdasarkan kata kunci.
const catatan = "Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.";
// includes: pemeriksaan ada atau tidak
console.log(catatan.includes("gula"));
console.log(catatan.includes("teh"));
// indexOf: posisi pertama; -1 berarti tidak ditemukan
console.log(catatan.indexOf("Tanya"));
console.log(catatan.indexOf("teh"));
// lastIndexOf: posisi kemunculan terakhir
console.log(catatan.lastIndexOf("Tanya"));
// startsWith dan endsWith: memeriksa ujung string
console.log(catatan.startsWith("Tanya"));
console.log(catatan.endsWith("kirim."));
// loop indexOf: menghitung semua kemunculan satu kata
let posisi = catatan.indexOf("Tanya");
let hitungan = 0;
while (posisi !== -1) {
hitungan++;
posisi = catatan.indexOf("Tanya", posisi + 1);
}
console.log(hitungan);
// matchAll: menemukan semua kode pesanan sekaligus
const log = "kopi-101, teh-300, kopi-205, gula-400, kopi-777";
const temuan = [...log.matchAll(/kopi-[0-9]+/g)];
console.log(temuan.length);
for (const hasil of temuan) {
console.log(hasil[0], "di indeks", hasil.index);
}Output yang Dihasilkan:
true
false
0
-1
35
true
true
3
3
kopi-101 di indeks 0
kopi-205 di indeks 19
kopi-777 di indeks 39Jalankan dengan node pencarian-pesan.js dan cocokkan hasilnya. Mari kita telaah baris-baris pentingnya:
- Baris 7–8:
includesmenjawab ada-tidaknya kata —"gula"ada,"teh"tidak ada. - Baris 11–12:
indexOfmelaporkan posisi"Tanya"pertama (0), dan-1untuk"teh"yang tidak ditemukan. - Baris 15:
lastIndexOfmenemukan “Tanya” ketiga pada indeks35. - Baris 22–28: loop while menghitung tiga kemunculan dengan menggeser titik mulai pencarian pada setiap putaran.
- Baris 32 (
[...log.matchAll(...)]): tiga kode pesanankopi-...dikumpulkan menjadi array, lengkap dengan indeks kemunculannya.
Perhatikan pattern /kopi-[0-9]+/g pada baris 32: kode pesanan tidak selalu kopi-101, bisa kopi-205 atau kopi-777, dan pencarian kata persis seperti includes tidak mampu menangkap keluarga teks semacam itu. Kemampuan mendeskripsikan bentuk teks itulah yang disebut regular expression — bahan utama chapter berikutnya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
pencarian-pesan.js
Unduh berkas// pencarian-pesan.js
// Siti menyaring catatan pesan pelanggan berdasarkan kata kunci.
const catatan = "Tanya stok kopi. Tanya harga gula. Tanya jadwal kirim.";
// includes: pemeriksaan ada atau tidak
console.log(catatan.includes("gula"));
console.log(catatan.includes("teh"));
// indexOf: posisi pertama; -1 berarti tidak ditemukan
console.log(catatan.indexOf("Tanya"));
console.log(catatan.indexOf("teh"));
// lastIndexOf: posisi kemunculan terakhir
console.log(catatan.lastIndexOf("Tanya"));
// startsWith dan endsWith: memeriksa ujung string
console.log(catatan.startsWith("Tanya"));
console.log(catatan.endsWith("kirim."));
// loop indexOf: menghitung semua kemunculan satu kata
let posisi = catatan.indexOf("Tanya");
let hitungan = 0;
while (posisi !== -1) {
hitungan++;
posisi = catatan.indexOf("Tanya", posisi + 1);
}
console.log(hitungan);
// matchAll: menemukan semua kode pesanan sekaligus
const log = "kopi-101, teh-300, kopi-205, gula-400, kopi-777";
const temuan = [...log.matchAll(/kopi-[0-9]+/g)];
console.log(temuan.length);
for (const hasil of temuan) {
console.log(hasil[0], "di indeks", hasil.index);
}