Soal 1Apa yang terjadi kalau kamu menjalankan localStorage.getItem("theme") dengan key yang belum pernah disimpan?
localStorage — Menyimpan Data di Browser
Menyimpan value di browser dengan setItem, getItem, dan removeItem milik localStorage, menyimpan array sebagai string JSON, serta menangani null dan batas kapasitas.
Kalau isi keranjang atau pengaturan tampilan pengguna kamu simpan di variabel, semuanya hilang saat halaman dimuat ulang atau ditutup, dan kembali ke keadaan awal saat halaman dibuka lagi. Sejauh ini, belum ada kode yang bisa menyimpan value agar tetap ada setelah halaman dimuat ulang.
Artikel ini membahas localStorage, yang menyimpan value di browser, dan string JSON yang dipakai untuk menyimpan array dan object.
Value yang Tetap Ada Setelah Halaman Ditutup — setItem dan getItem
Misalkan sebuah situs berita ingin mengingat ukuran huruf yang dipilih pengguna dan memakainya lagi di kunjungan berikutnya. Meskipun disimpan di variabel, seperti const fontSize = "large";, variabel hilang saat halaman dimuat ulang atau ditutup, jadi halaman yang dibuka berikutnya tidak bisa membacanya.
localStorage (tempat penyimpanan pasangan key dan value yang disediakan browser) menyimpan value dengan setItem(key, value), membacanya kembali dengan getItem(key), dan menghapusnya dengan removeItem(key).
Tempat penyimpanan ini dipisahkan per origin (bagian URL sebelum path — https://news.example pada https://news.example/settings), dan halaman-halaman dari origin yang sama membaca dan menulis data yang sama.
// Kalau masih ada value yang disimpan sebelumnya, hapus dulu supaya mulai dari keadaan tanpa data
localStorage.removeItem("fontSize");
// Simpan saat pengguna mengganti ukuran huruf menjadi besar
localStorage.setItem("fontSize", "large");
// Saat halaman dibuka, baca value yang disimpan lalu pakai
const fontSize = localStorage.getItem("fontSize");
console.log(fontSize); // large
// Menyimpan dengan key yang sama akan menggantikan value sebelumnya
localStorage.setItem("fontSize", "small");
console.log(localStorage.getItem("fontSize")); // small
- Halaman dan tab dari origin ini berbagi 1 localStorage
"fontSize"→"small"(diganti karena disimpan ke key yang sama)- Tetap ada setelah halaman ditutup atau dimuat ulang
- Variabel seperti
const fontSize - Variabel dibuat ulang saat dimuat ulang
- Punya localStorage sendiri
- Tidak bisa membaca
"fontSize"yang disimpan news.example
Kalau kamu membaca dengan getItem saat halaman dibuka dan menulis dengan setItem saat pengguna mengubah pengaturan, halaman tetap tampil dengan ukuran huruf yang sama meskipun dimuat ulang. Value yang disimpan tetap ada sampai kode halaman menghapusnya atau pengguna menghapusnya dari pengaturan browser.
Value yang Disimpan Terbawa ke Eksekusi Latihan Berikutnya
Console latihan menjalankan semua latihan JavaScript di situs ini pada origin yang sama, jadi semuanya berbagi 1 localStorage, dan isinya tetap ada meskipun halaman dibuka ulang. Supaya value yang disimpan di eksekusi sebelumnya tidak tercampur ke hasil kamu, setiap latihan dimulai dengan menghapus key yang dipakainya lewat removeItem.
Menyimpan Array dan Object — JSON.stringify
Sebuah situs pemesanan perjalanan menyimpan hotel-hotel favorit pengguna di dalam array dan ingin menampilkannya lagi di kunjungan berikutnya. Memberikan array langsung ke setItem tidak menimbulkan error, tapi value yang dibaca kembali tidak berisi ID maupun nama hotelnya.
setItem mengubah value yang diberikan menjadi string sebelum menyimpannya. Ubah array dan object menjadi string JSON dengan JSON.stringify sebelum disimpan, lalu kembalikan string yang dibaca menjadi array atau object semula dengan JSON.parse.
// Kalau masih ada value yang disimpan sebelumnya, hapus dulu
localStorage.removeItem("favoriteHotels");
const favoriteHotels = [{ id: "H-101", name: "Hotel Pelabuhan" }, { id: "H-204", name: "Wisma Stasiun" }];
// Kalau diberikan langsung, array diubah menjadi string saat disimpan
localStorage.setItem("favoriteHotels", favoriteHotels);
console.log(localStorage.getItem("favoriteHotels")); // [object Object],[object Object]
// Ubah menjadi string JSON sebelum disimpan
localStorage.setItem("favoriteHotels", JSON.stringify(favoriteHotels));
const saved = localStorage.getItem("favoriteHotels");
console.log(saved); // [{"id":"H-101","name":"Hotel Pelabuhan"},{"id":"H-204","name":"Wisma Stasiun"}]
// Kembalikan string yang dibaca menjadi array sebelum dipakai
const restored = JSON.parse(saved);
console.log(restored[1].name); // Wisma Stasiun
Angka dan boolean juga diubah diam-diam tanpa error, jadi kamu baru sadar saat perhitungan atau pengecekan if pada value yang dibaca kembali memberi hasil yang salah. Tabel di bawah menunjukkan string yang disimpan untuk setiap value yang diberikan ke setItem, dan apa yang terjadi saat value itu dibaca kembali.
| Value untuk setItem | String yang disimpan | Saat dibaca kembali |
|---|---|---|
| Angka 20 | "20" | "20" + 1 = "201" (pakai Number) |
| Boolean false | "false" | Truthy di if (pakai JSON.parse) |
| Array string ["A-1", "B-2"] | "A-1,B-2" | 1 string berkoma, bukan array |
Membaca Key yang Tidak Tersimpan — null dari getItem
Di situs resep, ID resep yang sudah dilihat disimpan sebagai riwayat, dan halaman menampilkan jumlahnya saat dibuka. Pengunjung yang baru pertama kali datang atau yang sudah menghapus riwayatnya tidak punya data tersimpan. Jadi, kalau kamu membaca length dari hasil JSON.parse dengan anggapan riwayatnya pasti ada, baris itu melempar TypeError.
Kalau getItem diberi key yang tidak tersimpan, yang dikembalikan adalah null, bukan undefined. Dengan menulis JSON.parse(localStorage.getItem(key)) ?? [], array kosong dipakai hanya saat tidak ada data yang tersimpan.
// Baca riwayat. Kalau tidak ada yang tersimpan, pakai array kosong
function loadHistory() {
return JSON.parse(localStorage.getItem("viewHistory")) ?? [];
}
// Kunjungan pertama — belum ada yang tersimpan, jadi getItem mengembalikan null
localStorage.removeItem("viewHistory");
console.log(localStorage.getItem("viewHistory")); // null
console.log(loadHistory().length); // 0
// Saat riwayat tersimpan — string dikembalikan menjadi array
localStorage.setItem("viewHistory", JSON.stringify(["R-12", "R-30"]));
console.log(loadHistory().length); // 2
// Setelah removeItem — kembali menjadi null
localStorage.removeItem("viewHistory");
console.log(loadHistory().length); // 0
Kalau kode pembacaan dijadikan function, pemanggilnya bisa memperlakukan hasilnya sebagai array tanpa mengecek null, bahkan setelah removeItem dipanggil saat logout. removeItem tidak melempar error meskipun key-nya tidak tersimpan, jadi kamu tidak perlu mengecek ada tidaknya data sebelum menghapus.
Mengembalikan Keranjang Setelah Dimuat Ulang — Function Simpan dan Muat
Berikutnya, keranjang di toko online harus tetap berisi saat halaman dimuat ulang setelah barang ditambahkan. Menambahkan barang dengan cart.push hanya mengubah variabel, jadi kalau baris penyimpanan terlewat di satu tempat saja, barang itu hilang saat halaman dimuat ulang.
Taruh proses penyimpanan di function saveCart dan proses pemuatan di function loadCart, lalu panggil keduanya tepat setelah keranjang berubah dan saat halaman dibuka. setItem bersifat synchronous (menyelesaikan penyimpanan dulu sebelum lanjut ke baris berikutnya), jadi tidak seperti fetch, value yang disimpan bisa dibaca di baris berikutnya tanpa await.
localStorage.removeItem("cart"); // Kalau masih ada keranjang yang disimpan sebelumnya, hapus
// Simpan keranjang sebagai string JSON. Tidak perlu await
function saveCart(cart) {
localStorage.setItem("cart", JSON.stringify(cart));
}
// Kembalikan keranjang yang disimpan menjadi array. Kalau tidak ada yang tersimpan, kembalikan keranjang kosong
function loadCart() {
return JSON.parse(localStorage.getItem("cart")) ?? [];
}
// Muat saat halaman dibuka, lalu simpan setelah menambahkan barang
const cart = loadCart();
cart.push({ id: "K-310", qty: 1 });
saveCart(cart);
// Sebagai pengganti memuat ulang, muat lagi dari string yang disimpan tanpa memakai variabel cart
const reloaded = loadCart();
console.log(reloaded.length, reloaded[0].id); // 1 K-310
Kalau semua proses yang mengubah keranjang dikumpulkan dalam 1 function yang memanggil saveCart di akhirnya, kamu tidak perlu menulis penyimpanan di setiap tempat pemanggilan, dan tidak mungkin lupa. Pemuatan juga sudah dibungkus di loadCart, jadi ?? [] tidak mungkin terlupa di salah satu tempat.
setItem Melempar Exception Saat Penyimpanan Penuh
Di Chrome, 1 origin bisa menyimpan sekitar 5,24 juta karakter, dihitung dari key dan value bersama-sama. Kalau melebihi itu, setItem melempar QuotaExceededError dan value-nya tidak tersimpan. Pembacaan dan penulisan bersifat synchronous, jadi halaman juga berhenti merespons selama value yang besar sedang disimpan. Pakai localStorage untuk value kecil seperti keranjang dan pengaturan.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Setelah localStorage.setItem("darkMode", false), apa yang terjadi kalau value yang dibaca kembali dipakai sebagai kondisi if?
Soal 3Kalau halaman dimuat ulang setelah cart.push(book) tanpa memanggil saveCart, apa yang dikembalikan loadCart()?