kodingup.camp

Beranda/JavaScript Mastery: Fundamentals

Representasi Teks dan Simbol

Modul 3 dari 164 menit bacaText and symbol representation

Isi modul

    Kenapa ini penting

    Hampir semua program mengolah teks: nama pengguna, pesan chat, alamat email, isi artikel, sampai kode program itu sendiri. Kamu sudah tahu komputer hanya menyimpan angka. Lalu bagaimana huruf "A", tanda "@", atau huruf "é" bisa tersimpan? Jawabannya: lewat tabel kesepakatan yang memetakan setiap karakter ke sebuah angka. Kalau kamu paham konsep ini, kamu tidak akan bingung saat melihat tulisan rusak seperti Café di website, atau saat panjang teks yang dihitung program ternyata berbeda dengan yang kamu lihat. Detail teknis standar seperti ASCII dan UTF-8 dibahas lebih dalam di modul Character translation systems. Di sini kita bangun intuisinya dulu.

    Konsep inti

    Karakter, glyph, dan kode

    Ada tiga hal berbeda yang sering dicampuradukkan:

    Analogi: nomor antrean di bank. Nomor "65" adalah kodenya, orang yang dipanggil adalah karakternya, sedangkan pakaian yang ia pakai hari itu adalah glyph-nya. Pakaiannya bisa ganti, tapi orangnya dan nomornya tetap.

    Character set dan encoding

    Kenapa perlu dua lapis? Karena nomor karakter bisa besar (emoji 😀 bernomor 128512), sedangkan satu byte hanya menampung 0-255. Encoding menentukan berapa byte yang dipakai dan bagaimana urutannya.

    Teks disimpan sebagai deretan angka

    Kata Hai disimpan kira-kira begini:

    Karakter H a i
    Kode 72 97 105
    Biner 01001000 01100001 01101001

    Perhatikan bahwa huruf besar dan huruf kecil punya kode berbeda: A = 65, a = 97. Bagi komputer, "Budi" dan "budi" adalah dua teks yang berbeda. Inilah sebabnya pencarian dan login sering mengubah teks ke huruf kecil dulu sebelum dibandingkan.

    Karakter tak terlihat

    Tidak semua karakter terlihat. Spasi punya kode 32. Baris baru (newline, ditulis \n dalam kode) punya kode 10. Tab (\t) punya kode 9. Windows tradisionalnya memakai dua karakter untuk baris baru (\r\n), sedangkan Linux dan macOS memakai satu (\n). Perbedaan kecil ini kadang bikin file teks terlihat "berantakan" saat dipindah antar sistem.

    Urutan abjad versi komputer

    Karena teks adalah angka, membandingkan teks sebenarnya membandingkan kode karakter satu per satu dari kiri. Akibatnya:

    Ini sumber bug klasik saat mengurutkan data. Solusinya akan kamu pelajari nanti (misalnya localeCompare untuk teks dan perbandingan angka untuk angka).

    Mojibake: teks rusak karena salah encoding

    Kalau teks disimpan dengan satu encoding tapi dibaca dengan encoding lain, hasilnya kacau. Contoh: kata Café disimpan sebagai UTF-8, tapi dibaca sebagai encoding lama Latin-1, maka tampil sebagai Café. Fenomena ini disebut mojibake (istilah Jepang untuk "karakter berubah bentuk"). Pencegahannya sederhana: pakai UTF-8 di mana-mana dan cantumkan <meta charset="UTF-8"> di setiap halaman HTML.

    Contoh kode

    // Melihat kode karakter dari setiap huruf
    const kata = "Hai";
    for (const huruf of kata) {
      console.log(huruf, "→", huruf.charCodeAt(0));
    }
    // → H → 72
    // → a → 97
    // → i → 105
    
    // Huruf besar dan kecil itu berbeda bagi komputer
    console.log("Budi" === "budi");                             // → false
    console.log("Budi".toLowerCase() === "budi".toLowerCase()); // → true
    
    // Perbandingan teks = perbandingan kode karakter
    console.log("B" < "a");   // → true  (66 < 97)
    console.log("10" < "9");  // → true  ("1" = 49 lebih kecil dari "9" = 57)
    
    // Mengurutkan nama tanpa peduli huruf besar/kecil
    const nama = ["budi", "Andi", "citra", "Dewi"];
    console.log([...nama].sort());
    // → [ 'Andi', 'Dewi', 'budi', 'citra' ]  (huruf besar duluan)
    console.log([...nama].sort((a, b) => a.localeCompare(b)));
    // → [ 'Andi', 'budi', 'citra', 'Dewi' ]
    

    Karakter tak terlihat dan jumlah byte:

    const teks = "Baris 1\nBaris 2";
    console.log(teks);
    // → Baris 1
    // → Baris 2
    console.log("\n".charCodeAt(0)); // → 10
    console.log(" ".charCodeAt(0));  // → 32
    
    // Jumlah karakter tidak selalu sama dengan jumlah byte
    const enc = new TextEncoder(); // encoding UTF-8
    console.log("A".length, enc.encode("A").length); // → 1 1
    console.log("é".length, enc.encode("é").length); // → 1 2
    

    Kesalahan umum

    1. Membandingkan teks tanpa menyamakan huruf besar/kecil. Email Budi@Mail.com dan budi@mail.com dianggap berbeda. Normalisasi dulu dengan toLowerCase() sebelum membandingkan.
    2. Mengurutkan angka yang disimpan sebagai teks. ["10", "9", "2"].sort() menghasilkan ["10", "2", "9"]. Ubah ke angka dulu sebelum diurutkan.
    3. Lupa <meta charset="UTF-8"> di HTML. Tanpa ini, browser bisa salah menebak encoding dan huruf beraksen atau emoji jadi rusak.
    4. Menganggap 1 karakter = 1 byte. Itu hanya berlaku untuk karakter ASCII dasar. Huruf é butuh 2 byte di UTF-8, emoji butuh 4 byte.

    Latihan

    1. Mudah, Cari tahu kode karakter dari huruf pertama namamu dan dari tanda @ menggunakan charCodeAt.
    2. Sedang, Tulis kode yang membandingkan dua username "AdminKu" dan " adminku " sehingga dianggap sama. Petunjuk: trim() menghapus spasi di awal dan akhir.
    3. Menantang, Tampilkan setiap karakter dari kata "Kode" beserta kodenya dalam bentuk biner 8 bit, misalnya K → 01001011.
    Lihat solusi

    1.

    console.log("S".charCodeAt(0)); // → 83 (contoh untuk nama "Sari")
    console.log("@".charCodeAt(0)); // → 64
    

    2.

    const a = "AdminKu";
    const b = " adminku ";
    const normal = (s) => s.trim().toLowerCase();
    console.log(normal(a) === normal(b)); // → true
    

    3.

    for (const huruf of "Kode") {
      const biner = huruf.charCodeAt(0).toString(2).padStart(8, "0");
      console.log(`${huruf} → ${biner}`);
    }
    // → K → 01001011
    // → o → 01101111
    // → d → 01100100
    // → e → 01100101
    

    Ringkasan

    Kuis pemahaman

    Pilih satu jawaban per soal. Penjelasan muncul setelah kamu menjawab.