Dalam JavaScript, data tekstual disimpan sebagai string. Tidak ada tipe terpisah untuk satu karakter.
Format internal untuk string selalu UTF-16, tidak terikat dengan pengkodean halaman.
Mari kita ingat kembali jenis-jenis kutipan.
String dapat diapit dalam tanda kutip tunggal, tanda kutip ganda, atau tanda kutip terbalik:
let single = 'tanda kutip tunggal'; let double = "tanda kutip ganda"; biarkan backtick = `backtick`;
Kutipan tunggal dan ganda pada dasarnya sama. Namun, backticks memungkinkan kita menyematkan ekspresi apa pun ke dalam string, dengan membungkusnya dalam ${…}
:
fungsi jumlah(a, b) { kembalikan a+b; } peringatan(`1 + 2 = ${jumlah(1, 2)}.`); // 1 + 2 = 3.
Keuntungan lain menggunakan backtick adalah memungkinkan string menjangkau beberapa baris:
biarkan Daftar Tamu = `Tamu: * Yohanes * Pete * Maria `; peringatan(Daftar Tamu); // daftar tamu, beberapa baris
Terlihat alami, bukan? Namun tanda kutip tunggal atau ganda tidak berfungsi seperti ini.
Jika kita menggunakannya dan mencoba menggunakan beberapa baris, akan ada kesalahan:
let guestList = "Tamu: // Kesalahan: Token tak terduga ILEGAL *Yohanes";
Kutipan tunggal dan ganda berasal dari zaman kuno penciptaan bahasa, ketika kebutuhan akan string multiline tidak diperhitungkan. Backtick muncul jauh kemudian dan karenanya lebih serbaguna.
Backtick juga memungkinkan kita menentukan “fungsi template” sebelum backtick pertama. Sintaksnya adalah: func`string`
. Fungsi func
dipanggil secara otomatis, menerima string dan ekspresi yang disematkan dan dapat memprosesnya. Fitur ini disebut “template yang diberi tag”, jarang terlihat, tetapi Anda dapat membacanya di MDN: Literal templat.
Masih dimungkinkan untuk membuat string multiline dengan tanda kutip tunggal dan ganda dengan menggunakan apa yang disebut “karakter baris baru”, ditulis sebagai n
, yang menunjukkan jeda baris:
let guestList = "Tamu:n * Johnn * Peten * Mary"; peringatan(Daftar Tamu); // daftar tamu multiline, sama seperti di atas
Sebagai contoh sederhana, kedua garis ini sama, hanya saja penulisannya berbeda:
let str1 = "HalonDunia"; // dua baris menggunakan "simbol baris baru" // dua baris menggunakan baris baru dan backtick normal biarkan str2 = `Halo Dunia`; peringatan(str1 == str2); // BENAR
Ada karakter khusus lain yang kurang umum:
Karakter | Keterangan |
---|---|
n | Baris baru |
r | Pada file teks Windows, kombinasi dua karakter rn mewakili terobosan baru, sedangkan pada OS non-Windows hanya n . Karena alasan historis, sebagian besar perangkat lunak Windows juga memahami n . |
' , " , ` | Kutipan |
\ | Garis miring terbalik |
t | tab |
b , f , v | Backspace, Form Feed, Tab Vertikal – disebutkan untuk kelengkapan, berasal dari masa lalu, tidak digunakan saat ini (Anda dapat melupakannya sekarang). |
Seperti yang Anda lihat, semua karakter khusus dimulai dengan karakter garis miring terbalik . Ini juga disebut “karakter pelarian”.
Karena ini sangat spesial, jika kita perlu menampilkan garis miring terbalik di dalam string, kita perlu menggandakannya:
alert( `Garis miring terbalik: \` ); // Garis miring terbalik:
Yang disebut tanda kutip “escape” '
, "
, `
digunakan untuk menyisipkan kutipan ke dalam string yang diberi tanda kutip yang sama.
Misalnya:
alert('Saya Walrus!' ); // Aku Walrusnya!
Seperti yang Anda lihat, kita harus mengawali tanda kutip bagian dalam dengan garis miring terbalik '
, karena jika tidak maka akan menunjukkan akhir string.
Tentu saja, hanya tanda kutip yang sama dengan tanda kutip yang terlampir yang perlu di-escape. Jadi, sebagai solusi yang lebih elegan, kita bisa beralih ke tanda kutip ganda atau backtick:
alert("Saya Walrus!"); // Aku Walrusnya!
Selain karakter khusus tersebut, terdapat juga notasi khusus untuk kode Unicode u…
, yang jarang digunakan dan dibahas dalam bab opsional tentang Unicode.
Properti length
memiliki panjang string:
alert( `Sayan`.panjang ); // 3
Perhatikan bahwa n
adalah satu karakter “khusus”, jadi panjangnya memang 3
.
length
adalah properti
Orang dengan latar belakang beberapa bahasa lain terkadang salah mengetik dengan memanggil str.length()
bukan hanya str.length
. Itu tidak berhasil.
Harap diperhatikan bahwa str.length
adalah properti numerik, bukan fungsi. Tidak perlu menambahkan tanda kurung setelahnya. Bukan .length()
, tapi .length
.
Untuk mendapatkan karakter pada posisi pos
, gunakan tanda kurung siku [pos]
atau panggil metode str.at(pos). Karakter pertama dimulai dari posisi nol:
biarkan str = `Halo`; // karakter pertama peringatan( str[0] ); // H waspada( str.at(0) ); // H // karakter terakhir peringatan( str[str.panjang - 1] ); // Hai waspada( str.at(-1) );
Seperti yang Anda lihat, metode .at(pos)
memiliki keuntungan dalam memungkinkan posisi negatif. Jika pos
negatif, maka dihitung dari ujung string.
Jadi .at(-1)
berarti karakter terakhir, dan .at(-2)
adalah karakter sebelumnya, dan seterusnya.
Tanda kurung siku selalu menghasilkan undefined
untuk indeks negatif, misalnya:
biarkan str = `Halo`; peringatan( str[-2] ); // belum diartikan waspada( str.at(-2) ); // aku
Kita juga dapat mengulangi karakter menggunakan for..of
:
for (biarkan karakter "Halo") { peringatan(karakter); // H,e,l,l,o (char menjadi "H", lalu "e", lalu "l" dst) }
String tidak dapat diubah dalam JavaScript. Tidak mungkin mengubah karakter.
Mari kita coba untuk menunjukkan bahwa itu tidak berhasil:
biarkan str = 'Hai'; str[0] = 'h'; // kesalahan peringatan( str[0] ); // tidak berfungsi
Solusi yang biasa dilakukan adalah membuat string baru dan menugaskannya ke str
bukan string lama.
Misalnya:
biarkan str = 'Hai'; str = 'h' + str[1]; // ganti stringnya peringatan(str); // Hai
Di bagian berikut, kita akan melihat lebih banyak contoh mengenai hal ini.
Metode toLowerCase() dan toUpperCase() mengubah huruf besar/kecil:
peringatan('Antarmuka'.toUpperCase() ); // ANTARMUKA peringatan('Antarmuka'.toLowerCase() ); // antarmuka
Atau, jika kita ingin satu karakter menggunakan huruf kecil:
peringatan('Antarmuka'[0].toLowerCase() ); // 'Saya'
Ada beberapa cara untuk mencari substring dalam sebuah string.
Metode pertama adalah str.indexOf(substr, pos).
Ia mencari substr
di str
, mulai dari posisi tertentu pos
, dan mengembalikan posisi di mana kecocokan ditemukan atau -1
jika tidak ada yang ditemukan.
Misalnya:
let str = 'Widget dengan id'; peringatan( str.indexOf('Widget') ); // 0, karena 'Widget' ditemukan di awal peringatan( str.indexOf('widget') ); // -1, tidak ditemukan, pencarian peka huruf besar-kecil peringatan( str.indexOf("id") ); // 1, "id" ditemukan pada posisi 1 (..idget dengan id)
Parameter opsional kedua memungkinkan kita memulai pencarian dari posisi tertentu.
Misalnya, kemunculan pertama "id"
ada di posisi 1
. Untuk mencari kejadian selanjutnya, mari kita mulai pencarian dari posisi 2
:
let str = 'Widget dengan id'; peringatan( str.indexOf('id', 2) ) // 12
Jika kita tertarik pada semua kejadian, kita dapat menjalankan indexOf
dalam satu lingkaran. Setiap panggilan baru dilakukan dengan posisi setelah pertandingan sebelumnya:
let str = 'Lici seperti rubah, sekuat lembu'; biarkan target = 'sebagai'; // ayo kita mencarinya misalkan pos = 0; sementara (benar) { biarkan foundPos = str.indexOf(target, pos); if (foundPos == -1) rusak; alert( `Ditemukan di ${foundPos}` ); pos = ditemukanPos + 1; // melanjutkan pencarian dari posisi berikutnya }
Algoritme yang sama dapat dibuat lebih pendek:
let str = "Licik seperti rubah, sekuat lembu"; biarkan target = "sebagai"; misalkan pos = -1; while ((pos = str.indexOf(target, pos + 1)) != -1) { peringatan( pos ); }
str.lastIndexOf(substr, position)
Ada juga metode serupa str.lastIndexOf(substr, position) yang mencari dari akhir string hingga awal.
Ini akan mencantumkan kejadian dalam urutan terbalik.
Ada sedikit ketidaknyamanan dengan indexOf
dalam pengujian if
. Kita tidak bisa memasukkannya ke dalam if
seperti ini:
let str = "Widget dengan id"; if (str.indexOf("Widget")) { alert("Kami menemukannya"); // tidak berhasil! }
alert
pada contoh di atas tidak muncul karena str.indexOf("Widget")
mengembalikan 0
(artinya menemukan kecocokan di posisi awal). Benar, tetapi if
menganggap 0
false
.
Jadi, kita harus memeriksa -1
, seperti ini:
let str = "Widget dengan id"; jika (str.indexOf("Widget") != -1) { alert("Kami menemukannya"); // berfungsi sekarang! }
Metode yang lebih modern str.includes(substr, pos) mengembalikan true/false
bergantung pada apakah str
berisi substr
di dalamnya.
Ini adalah pilihan yang tepat jika kita perlu menguji pertandingan, namun tidak memerlukan posisinya:
alert("Widget dengan id".includes("Widget") ); // BENAR alert( "Halo".includes("Sampai jumpa") ); // PALSU
Argumen opsional kedua dari str.includes
adalah posisi untuk memulai pencarian:
peringatan("Widget".termasuk("id") ); // BENAR peringatan("Widget".termasuk("id",3) ); // salah, dari posisi 3 tidak ada "id"
Metode str.startsWith dan str.endsWith melakukan persis seperti yang mereka katakan:
alert( "Widget".startsWith("Lebar") ); // benar, "Widget" dimulai dengan "Wid" alert("Widget".endsWith("dapatkan") ); // benar, "Widget" diakhiri dengan "dapatkan"
Ada 3 metode dalam JavaScript untuk mendapatkan substring: substring
, substr
dan slice
.
str.slice(start [, end])
Mengembalikan bagian string dari start
hingga (tetapi tidak termasuk) end
.
Misalnya:
biarkan str = "merangkai"; waspada( str.slice(0, 5) ); // 'strin', substring dari 0 sampai 5 (tidak termasuk 5) waspada( str.slice(0, 1) ); // 's', dari 0 sampai 1, tapi tidak termasuk 1, jadi hanya karakter di 0
Jika tidak ada argumen kedua, maka slice
akan berlanjut hingga akhir string:
biarkan str = "merangkai"; waspada( str.irisan(2) ); // 'ringify', dari posisi ke-2 hingga akhir
Nilai negatif untuk start/end
juga dimungkinkan. Artinya posisi dihitung dari ujung senar:
biarkan str = "merangkai"; // mulai dari posisi ke-4 dari kanan, berakhir di posisi ke-1 dari kanan waspada( str.slice(-4, -1) ); // 'gif'
str.substring(start [, end])
Mengembalikan bagian string antara start
dan end
(tidak termasuk end
).
Ini hampir sama dengan slice
, tetapi memungkinkan start
lebih besar dari end
(dalam hal ini hanya menukar nilai start
dan end
).
Misalnya:
biarkan str = "merangkai"; // ini sama untuk substring peringatan( str.substring(2, 6) ); // "dering" peringatan( str.substring(6, 2) ); // "dering" // ...tapi tidak untuk irisan: waspada( str.slice(2, 6) ); // "dering" (sama) waspada( str.slice(6, 2) ); // "" (string kosong)
Argumen negatif (tidak seperti irisan) tidak didukung, argumen tersebut diperlakukan sebagai 0
.
str.substr(start [, length])
Mengembalikan bagian string dari start
, dengan length
tertentu.
Berbeda dengan metode sebelumnya, metode ini memungkinkan kita menentukan length
bukan posisi akhir:
biarkan str = "merangkai"; peringatan( str.substr(2, 4) ); // 'ring', dari posisi ke-2 dapatkan 4 karakter
Argumen pertama mungkin negatif, jika dihitung dari akhir:
biarkan str = "merangkai"; peringatan( str.substr(-4, 2) ); // 'gi', dari posisi ke-4 mendapat 2 karakter
Metode ini terdapat dalam Lampiran B spesifikasi bahasa. Artinya, hanya mesin Javascript yang dihosting di browser yang boleh mendukungnya, dan tidak disarankan untuk menggunakannya. Dalam praktiknya, hal ini didukung di mana-mana.
Mari kita rekap metode berikut untuk menghindari kebingungan:
metode | memilih… | negatif |
---|---|---|
slice(start, end) | dari start hingga end (tidak termasuk end ) | memungkinkan hal-hal negatif |
substring(start, end) | antara start dan end (tidak termasuk end ) | nilai negatif berarti 0 |
substr(start, length) | dari start dapatkan karakter length | memungkinkan start yang negatif |
Yang mana yang harus dipilih?
Semuanya bisa melakukan pekerjaan itu. Secara formal, substr
memiliki kelemahan kecil: substr tidak dijelaskan dalam spesifikasi inti JavaScript, tetapi dalam Lampiran B, yang mencakup fitur khusus browser yang ada terutama karena alasan historis. Jadi, lingkungan non-browser mungkin gagal mendukungnya. Namun dalam praktiknya, ini berhasil di mana-mana.
Dari dua varian lainnya, slice
sedikit lebih fleksibel, memungkinkan argumen negatif dan penulisan lebih singkat.
Jadi, untuk penggunaan praktisnya cukup mengingat slice
saja.
Seperti yang kita ketahui dari bab Perbandingan, string dibandingkan karakter demi karakter dalam urutan abjad.
Meski begitu, ada beberapa keanehan.
Huruf kecil selalu lebih besar dari huruf besar:
peringatan('a' > 'Z' ); // BENAR
Huruf dengan tanda diakritik “tidak berurutan”:
alert( 'Österreich' > 'Selandia' ); // BENAR
Hal ini mungkin menimbulkan hasil yang aneh jika kita mengurutkan nama negara ini. Biasanya orang mengira Zealand
akan menyusul Österreich
dalam daftar.
Untuk memahami apa yang terjadi, kita harus menyadari bahwa string dalam Javascript dikodekan menggunakan UTF-16. Artinya: setiap karakter memiliki kode numerik yang sesuai.
Ada metode khusus yang memungkinkan untuk mendapatkan karakter untuk kode dan kembali:
str.codePointAt(pos)
Mengembalikan angka desimal yang mewakili kode karakter pada posisi pos
:
// beda huruf besar dan kecil mempunyai kode berbeda peringatan("Z".codePointAt(0) ); // 90 peringatan( "z".codePointAt(0) ); // 122 peringatan( "z".codePointAt(0).toString(16) ); // 7a (jika kita membutuhkan nilai heksadesimal)
String.fromCodePoint(code)
Membuat karakter dengan code
numeriknya
peringatan( String.fromCodePoint(90) ); // Z peringatan( String.fromCodePoint(0x5a) ); // Z (kita juga bisa menggunakan nilai hex sebagai argumen)
Sekarang mari kita lihat karakter dengan kode 65..220
(abjad latin dan sedikit tambahan) dengan membuat string darinya:
biarkan str = ''; untuk (misalkan i = 65; i <= 220; i++) { str += String.dariCodePoint(i); } peringatan(str); // Keluaran: // ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ € ‚ƒ„ // ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜ
Melihat? Karakter kapital didahulukan, lalu beberapa karakter khusus, lalu karakter huruf kecil, dan Ö
di dekat akhir keluaran.
Sekarang menjadi jelas mengapa a > Z
.
Karakter dibandingkan dengan kode numeriknya. Semakin besar kode berarti semakin besar karakternya. Kode a
(97) lebih besar dibandingkan kode Z
(90).
Semua huruf kecil ditempatkan setelah huruf besar karena kodenya lebih besar.
Beberapa huruf seperti Ö
menonjol dari alfabet utama. Di sini, kodenya lebih besar dari apa pun mulai dari a
hingga z
.
Algoritme yang “benar” untuk melakukan perbandingan string ternyata lebih rumit dari yang terlihat, karena alfabet berbeda untuk bahasa yang berbeda.
Jadi, browser perlu mengetahui bahasa yang akan dibandingkan.
Untungnya, browser modern mendukung standar internasionalisasi ECMA-402.
Ini menyediakan metode khusus untuk membandingkan string dalam berbagai bahasa, mengikuti aturan mereka.
Panggilan str.localeCompare(str2) mengembalikan bilangan bulat yang menunjukkan apakah str
lebih kecil, sama atau lebih besar dari str2
sesuai dengan aturan bahasa:
Mengembalikan angka negatif jika str
kurang dari str2
.
Mengembalikan angka positif jika str
lebih besar dari str2
.
Mengembalikan 0
jika setara.
Misalnya:
alert( 'Österreich'.localeCompare('Selandia') ); // -1
Metode ini sebenarnya memiliki dua argumen tambahan yang ditentukan dalam dokumentasi, yang memungkinkannya menentukan bahasa (secara default diambil dari lingkungan, urutan huruf bergantung pada bahasa) dan menyiapkan aturan tambahan seperti sensitivitas huruf besar-kecil atau harusnya "a"
dan "á"
diperlakukan sama, dll.
Ada 3 jenis kutipan. Backticks memungkinkan string menjangkau beberapa baris dan menyematkan ekspresi ${…}
.
Kita dapat menggunakan karakter khusus, seperti pemisah baris n
.
Untuk mendapatkan karakter, gunakan metode: []
atau at
.
Untuk mendapatkan substring, gunakan: slice
atau substring
.
Untuk menggunakan huruf kecil/besar pada sebuah string, gunakan: toLowerCase/toUpperCase
.
Untuk mencari substring, gunakan: indexOf
, atau includes/startsWith/endsWith
untuk pemeriksaan sederhana.
Untuk membandingkan string menurut bahasa, gunakan: localeCompare
, jika tidak, string akan dibandingkan berdasarkan kode karakter.
Ada beberapa metode bermanfaat lainnya dalam string:
str.trim()
– menghapus spasi (“trim”) dari awal dan akhir string.
str.repeat(n)
– mengulangi string n
kali.
…dan masih banyak lagi yang bisa ditemukan di manual.
String juga memiliki metode untuk melakukan pencarian/penggantian dengan ekspresi reguler. Tapi itu topik besar, jadi dijelaskan di bagian tutorial terpisah Ekspresi reguler.
Selain itu, untuk saat ini penting untuk mengetahui bahwa string didasarkan pada pengkodean Unicode, dan karenanya ada masalah dengan perbandingan. Ada lebih banyak tentang Unicode di bab Unicode, Internal string.
pentingnya: 5
Tulis fungsi ucFirst(str)
yang mengembalikan string str
dengan karakter pertama huruf besar, misalnya:
ucPertama("john") == "John";
Buka kotak pasir dengan tes.
Kita tidak dapat “mengganti” karakter pertama, karena string dalam JavaScript tidak dapat diubah.
Tapi kita bisa membuat string baru berdasarkan string yang sudah ada, dengan karakter pertama dalam huruf besar:
biarkan newStr = str[0].toUpperCase() + str.slice(1);
Tapi ada masalah kecil. Jika str
kosong, maka str[0]
adalah undefined
, dan karena undefined
tidak memiliki metode toUpperCase()
, kita akan mendapatkan kesalahan.
Cara termudah adalah dengan menambahkan tes untuk string kosong, seperti ini:
fungsi ucPertama(str) { jika (!str) kembalikan str; kembalikan str[0].toUpperCase() + str.slice(1); } peringatan( ucPertama("john") ); // Yohanes
Buka solusi dengan pengujian di kotak pasir.
pentingnya: 5
Tulis fungsi checkSpam(str)
yang mengembalikan true
jika str
berisi 'viagra' atau 'XXX', jika tidak, false
.
Fungsinya harus peka huruf besar-kecil:
checkSpam('beli ViAgRA sekarang') == benar checkSpam('gratis xxxxx') == benar checkSpam("kelinci tidak bersalah") == salah
Buka kotak pasir dengan tes.
Untuk membuat penelusuran tidak membedakan huruf besar-kecil, mari ubah string menjadi huruf kecil lalu telusuri:
fungsi checkSpam(str) { biarkan lowerStr = str.toLowerCase(); kembalikan LowerStr.includes('viagra') || lowerStr.termasuk('xxx'); } alert( checkSpam('beli ViAgRA sekarang') ); peringatan( checkSpam('gratis xxxxx') ); alert( checkSpam("kelinci tidak bersalah") );
Buka solusi dengan pengujian di kotak pasir.
pentingnya: 5
Buat fungsi truncate(str, maxlength)
yang memeriksa panjang str
dan, jika melebihi maxlength
– ganti akhir str
dengan karakter elipsis "…"
, untuk membuat panjangnya sama dengan maxlength
.
Hasil dari fungsi tersebut harus berupa string yang terpotong (jika diperlukan).
Misalnya:
truncate("Yang ingin saya sampaikan mengenai topik ini adalah:", 20) == "Yang ingin saya sampaikan..." truncate("Halo semuanya!", 20) == "Halo semuanya!"
Buka kotak pasir dengan tes.
Panjang maksimalnya harus maxlength
, jadi kita perlu memotongnya sedikit lebih pendek, untuk memberi ruang bagi elipsis.
Perhatikan bahwa sebenarnya ada satu karakter Unicode untuk elipsis. Itu bukan tiga titik.
fungsi memotong(str, panjang maksimal) { kembali (str.panjang > panjang maksimal)? str.slice(0, panjang maksimal - 1) + '…' : str; }
Buka solusi dengan pengujian di kotak pasir.
pentingnya: 4
Kami memiliki biaya dalam bentuk "$120"
. Artinya: tanda dolar didahulukan, baru nomornya.
Buat fungsi extractCurrencyValue(str)
yang akan mengekstrak nilai numerik dari string tersebut dan mengembalikannya.
Contohnya:
peringatan( ekstrakCurrencyValue('$120') === 120 ); // BENAR
Buka kotak pasir dengan tes.
fungsi ekstrakCurrencyValue(str) { return +str.slice(1); }
Buka solusi dengan pengujian di kotak pasir.