Ilustrasi rak kotak bernomor dan kartu kunci nilai, simbol array dan object

Sejauh ini variabel kita cuma bisa menyimpan satu nilai. Satu nama, satu umur, satu skor. Tapi dunia nyata tidak sesederhana itu. Daftar belanja punya puluhan item. Data satu murid punya nama, umur, alamat, dan nilai. Kalau setiap data butuh satu variabel, program 1000 data butuh 1000 variabel. Itu bukan programming, itu penyiksaan.

Di artikel sebelumnya kita belajar membungkus kode dengan function supaya rapi. Sekarang kita belajar membungkus data supaya rapi. JavaScript punya dua wadah serbaguna: array untuk daftar berurutan, dan object untuk data berlabel. Keduanya akan kamu pakai di hampir setiap baris kode JavaScript mulai hari ini, termasuk di proyek to-do list di akhir seri.

Di akhir artikel ini kamu bisa bikin daftar, menambah dan mengurangi isinya, mengakses data berlapis, dan yang paling penting: tahu kapan pakai array dan kapan pakai object.

Array: Rak Bernomor di Gudang

Kembali ke analogi gudang. Bayangkan satu rak panjang berisi kotak-kotak yang bernomor urut mulai dari 0: kotak 0, kotak 1, kotak 2. Itulah array, daftar nilai yang berurutan dan diakses lewat nomor urut yang disebut index.

let buah = ["apel", "mangga", "jeruk"];
console.log(buah[0]); // "apel" (kotak nomor 0)
console.log(buah[2]); // "jeruk" (kotak nomor 2)
console.log(buah.length); // 3 (jumlah kotak)

Dua hal yang wajib dihafal di luar kepala: index dimulai dari 0, bukan 1, dan length menghitung jumlah isi. Jadi kotak terakhir selalu bernomor length - 1. Ini sumber off-by-one error paling legendaris di dunia programming, jadi biasakan.

Mengubah isi kotak semudah menunjuk nomornya:

buah[1] = "durian"; // kotak 1 sekarang berisi durian
console.log(buah); // ["apel", "durian", "jeruk"]

Berhenti dan tebak dulu! Apa outputnya?

let angka = [10, 20, 30];
console.log(angka[angka.length - 1]);
Jawaban: 30. angka.length = 3, jadi angka[3 - 1] = angka[2] = 30. Pola array[array.length - 1] ini adalah cara baku mengambil item terakhir tanpa peduli berapa panjang daftarnya. Hafalkan polanya, bukan angkanya.

Menambah dan Mengurangi Isi Daftar

Rak yang tidak bisa ditambah atau dikurangi isinya tidak berguna. Array punya empat method (function bawaan) untuk itu. Bayangkan antrean orang:

  • push(): orang baru datang dari belakang, ikut antre di ujung. buah.push("pisang")
  • pop(): orang paling belakang keluar antrean, dan kamu tahu siapa yang keluar (nilai kembalinya).
  • unshift(): orang baru menyerobot ke depan antrean.
  • shift(): orang paling depan keluar antrean.
let antrean = ["Budi", "Sinta"];
antrean.push("Agus");   // ["Budi", "Sinta", "Agus"]
let keluar = antrean.shift(); // "Budi" keluar, antrean = ["Sinta", "Agus"]
console.log(keluar); // "Budi"

Perhatikan: push dan unshift mengembalikan panjang baru array, sedangkan pop dan shift mengembalikan item yang dikeluarkan. Beda ini penting kalau kamu menyimpan hasil method-nya ke variabel. Kalau ragu, jangan tebak, cek di console.

Berhenti dan tebak dulu! Apa isi tumpukan di akhir?

let tumpukan = ["a", "b"];
tumpukan.push("c");
tumpukan.pop();
tumpukan.unshift("z");
Jawaban: ["z", "a", "b"]. Jejaknya: mulai ["a", "b"], push "c" jadi ["a", "b", "c"], pop mengeluarkan "c" jadi ["a", "b"], unshift "z" ke depan jadi ["z", "a", "b"]. Kuncinya: push/pop main di belakang, shift/unshift main di depan. Jejak satu per satu, jangan lompat ke kesimpulan.

Object: Lemari Berlabel, Bukan Bernomor

Kalau array itu rak bernomor, object itu lemari berlaci berlabel. Setiap laci punya label (disebut key) dan isi (disebut value). Cocok untuk data yang tiap bagiannya punya nama dan makna sendiri:

let murid = {
  nama: "Dita",
  umur: 16,
  kelas: "XI RPL"
};
console.log(murid.nama); // "Dita"
console.log(murid.umur); // 16

Cara mengaksesnya dengan dot notation: nama object, titik, nama label. Sederhana dan jadi pilihan utama kalau labelnya sudah kamu ketahui dari awal.

Ada cara kedua, bracket notation, yang wajib kamu kenal karena punya kekuatan khusus:

let label = "nama";
console.log(murid[label]); // "Dita"
console.log(murid["kelas"]); // "XI RPL"

Bedanya: di dalam kurung siku kamu bisa menaruh variabel. Ini berguna kalau label yang mau diakses baru diketahui saat program berjalan, misalnya dari pilihan pengguna. Aturan praktisnya: pakai dot notation kalau labelnya sudah pasti (murid.nama), pakai bracket kalau labelnya dinamis atau mengandung karakter aneh seperti spasi.

Dua Persepsi yang Sering Salah

Pertama: "array dan object itu dua dunia yang terpisah." Sebenarnya mereka sering bersarang. Daftar murid itu array yang tiap itemnya object. Data satu murid itu object yang salah satu labelnya berisi array nilai ujian. Dunia nyata memang berlapis-lapis, dan JavaScript mengizinkannya:

let kelas = [
  { nama: "Dita", nilai: 85 },
  { nama: "Budi", nilai: 70 }
];
console.log(kelas[1].nama); // "Budi"

Bacanya dari kiri ke kanan: ambil item nomor 1 dari array kelas (dapat object Budi), lalu ambil label nama-nya. Kalau bingung, pecah jadi dua langkah dengan variabel perantara, tidak ada yang melarang.

Kedua: "const berarti array/object-nya tidak bisa diubah." Ini lanjutan jebakan dari artikel variabel. const mengunci kotaknya, bukan isinya:

const buah = ["apel"];
buah.push("mangga"); // BOLEH! Isi kotak boleh diutak-atik
buah = ["jeruk"];    // ERROR! Kotaknya tidak boleh diganti

Analoginya: const itu seperti lemari yang dipaku ke lantai. Kamu tidak bisa mengganti lemarinya, tapi lacinya tetap bisa dibuka tutup dan isinya bisa ditambah. Justru inilah pola yang paling umum di kode profesional: const untuk array dan object, karena yang dijaga adalah "wadahnya tetap wadah yang sama".

Berhenti dan tebak dulu! Apa outputnya?

const user = { nama: "Eko", umur: 20 };
user.umur = 21;
console.log(user.umur);
Jawaban: 21, tanpa error. user.umur = 21 itu mengutak-atik isi object, bukan mengganti kotaknya. Yang dilarang const hanya user = { ... } (mengganti seluruh wadah). Ingat mantra: const mengunci wadah, bukan isi.

Kapan Pakai Array, Kapan Pakai Object?

Aturan jempolnya sederhana. Tanya ke datamu: "apakah urutannya penting dan itemnya sejenis?" Kalau ya, pakai array: daftar belanja, daftar nilai, antrean. "Apakah tiap bagian punya nama dan peran sendiri?" Kalau ya, pakai object: data pengguna, konfigurasi, satu baris data murid.

Dan seperti yang sudah kamu lihat, jawaban yang benar sering kali "keduanya": array of object. Daftar (array) yang tiap itemnya adalah data berlabel (object). Pola ini akan muncul terus di kariermu, dari data API sampai database.

Kuis cepat: Data mana yang paling pas disimpan sebagai object?

Latihan: Ubah, Jangan Cuma Dibaca

  1. Ubah daftar jadi program kasir mini. Buat array harga = [15000, 25000, 10000]. Tulis loop for...of yang menjumlahkan semuanya ke variabel total, lalu cetak. Setelah berhasil, tambah fitur: pakai push untuk menambah satu barang baru sebelum dihitung.
  2. Bikin object profil lalu ubah. Buat object profil berisi nama, kota, dan hobi (hobinya berupa array!). Cetak hobinya yang pertama (profil.hobi[0]), lalu tambah satu hobi baru dengan push, lalu ubah kotanya.
  3. Gabungkan jadi daftar murid. Buat array berisi 3 object murid (nama + nilai). Tulis function rataRata(kelas) yang me-return rata-rata nilai sekelas. Ini menggabungkan semua yang kamu pelajari: array, object, loop, dan function.

Habis Ini ke Mana?

Sejauh ini semua kodemu hidup di console: input ditulis manual, output dibaca di console. Program yang beneran dipakai orang tidak begitu, ia hidup di halaman web: ada tombol yang bisa diklik, teks yang bisa berubah, daftar yang bisa bertambah.

Artikel berikutnya, DOM di JavaScript dan Cara Mengendalikan Halaman Web, adalah jembatan paling seru di seri ini. Kamu akan belajar cara JavaScript "menggapai" elemen HTML dan mengubahnya seenaknya. Dari sinilah web yang statis berubah jadi web yang hidup.