Pengunjung toko Budi, Siti, mengatur tema halaman menjadi gelap. Begitu ia membuka toko lagi besoknya, tema kembali terang — pilihan tadi hilang setiap halaman dimuat ulang. Variabel biasa memang tidak bisa membantu: seluruh nilai JavaScript ikut terhapus ketika halaman diganti. Yang dibutuhkan adalah tempat penyimpanan yang dikelola browser dan bertahan di luar siklus hidup halaman.
Jawabannya adalah Web Storage: dua penyimpanan kunci-nilai yang disediakan browser per asal (origin) situs. localStorage menyimpan data jangka panjang yang tetap ada setelah browser ditutup, sedangkan sessionStorage menyimpan data untuk satu tab saja. Keduanya punya method yang sama persis, sehingga pola yang kita pelajari di chapter ini berlaku untuk keduanya.
Menyimpan dan Membaca Nilai #
Aturan dasarnya empat method: setItem(kunci, nilai) untuk menulis, getItem(kunci) untuk membaca, removeItem(kunci) untuk menghapus satu kunci, dan clear() untuk mengosongkan seluruh penyimpanan. Berkas berikut memakai localStorage untuk preferensi pengunjung:
// preferensi-toko.js — menyimpan dan membaca preferensi di localStorage
// --- 1. menulis pasangan kunci-nilai ---
localStorage.setItem("nama-pengunjung", "Siti");
localStorage.setItem("tema", "gelap");
// --- 2. membaca nilai berdasarkan kuncinya ---
console.log("nama :", localStorage.getItem("nama-pengunjung"));
console.log("tema :", localStorage.getItem("tema"));
console.log("kupon:", localStorage.getItem("kupon")); // kunci tidak ada -> null
// --- 3. menimpa nilai lama dengan kunci yang sama ---
localStorage.setItem("tema", "terang");
console.log("tema baru:", localStorage.getItem("tema"));
// --- 4. menghapus satu kunci ---
localStorage.removeItem("nama-pengunjung");
console.log("nama setelah removeItem:", localStorage.getItem("nama-pengunjung"));Keluaran berikut dicatat dari eksekusi nyata berkas ini di lingkungan DOM jsdom; console browser menghasilkan deretan yang sama karena method Web Storage berperilaku identik:
Output yang Dihasilkan (console browser):
nama : Siti
tema : gelap
kupon: null
tema baru: terang
nama setelah removeItem: nullMari kita telaah baris-baris pentingnya:
- Baris 4–5 (
setItem(...)): setiap data disimpan sebagai pasangan kunci-nilai dengan kunci string. Nilai yang sama kuncinya akan menimpa nilai lama — tidak ada peringatan penimpaan. - Baris 8–10 (
getItem(...)):getItemmengembalikan string yang tersimpan, ataunullbila kuncinya tidak pernah ditulis. Pemeriksaannullinilah cara kita membedakan “belum pernah diatur” dari nilai asli. - Baris 13–14 (menimpa
tema):setItemdengan kunci yang sama mengganti nilai lama. Tidak ada method “ubah” terpisah — menulis ulang adalah cara mengubah. - Baris 17–18 (
removeItem(...)): satu kunci dihapus, dan pembacaan berikutnya kembali menghasilkannull. Untuk mengosongkan seluruh penyimpanan asal, tersedialocalStorage.clear().
Ada satu batasan format yang perlu dipahami sejak awal: Web Storage hanya menyimpan string. Angka yang disimpan via setItem("stok", 4) dibaca kembali sebagai string "4", dan object yang disimpan langsung berubah menjadi teks "[object Object]" — bukan isinya. Untuk data berstruktur, kita butuh satu langkah tambahan.
Tiga method kecil melengkapi pengelolaan penyimpanan. localStorage.length menghitung jumlah pasangan yang tersimpan; localStorage.key(indeks) membaca nama kunci berdasarkan posisinya — berguna untuk menginventarisasi isi penyimpanan dengan loop; dan localStorage.clear() mengosongkan semuanya sekaligus. Untuk toko Budi, clear() sebaiknya dipakai hemat: mengosongkan storage berarti menghapus preferensi seluruh pengunjung yang tersimpan di perangkat masing-masing, bukan hanya satu kunci.
Menyimpan Object dengan JSON Round-Trip #
Solusi standarnya adalah round-trip JSON: object diubah menjadi string JSON dengan JSON.stringify() sebelum disimpan, lalu string itu dikembalikan menjadi object dengan JSON.parse() setelah dibaca. Berkas berikut menyimpan isi keranjang belanja Siti:
// keranjang-json.js — menyimpan array object dengan round-trip JSON
const keranjang = [
{ judul: "Kamus Mini Bahasa", jumlah: 1 },
{ judul: "Cerita di Sekitar Kita", jumlah: 2 },
];
// --- 1. object diubah menjadi string JSON sebelum disimpan ---
localStorage.setItem("keranjang", JSON.stringify(keranjang));
console.log("tersimpan :", localStorage.getItem("keranjang"));
// --- 2. string JSON dibaca lalu dikembalikan menjadi array ---
const tersimpan = JSON.parse(localStorage.getItem("keranjang"));
for (const buku of tersimpan) {
console.log(`${buku.judul} x${buku.jumlah}`);
}
// --- 3. array hasil parse adalah object biasa: bisa diubah lalu disimpan lagi ---
tersimpan.push({ judul: "Peta Jalur Sepeda", jumlah: 1 });
localStorage.setItem("keranjang", JSON.stringify(tersimpan));
const terbaru = JSON.parse(localStorage.getItem("keranjang"));
console.log("jumlah item:", terbaru.length);
// --- 4. sessionStorage memakai method yang sama ---
sessionStorage.setItem("langkah-checkout", "pengiriman");
console.log("langkah :", sessionStorage.getItem("langkah-checkout"));Keluaran berikut dicatat dari eksekusi nyata di lingkungan DOM jsdom:
Output yang Dihasilkan (console browser):
tersimpan : [{"judul":"Kamus Mini Bahasa","jumlah":1},{"judul":"Cerita di Sekitar Kita","jumlah":2}]
Kamus Mini Bahasa x1
Cerita di Sekitar Kita x2
jumlah item: 3
langkah : pengirimanMari kita bedah:
- Baris 9 (
JSON.stringify(keranjang)): array object diubah menjadi satu string JSON, lalu disimpan sebagai nilai kuncikeranjang. Baris keluaran pertama memperlihatkan bentuk string itu — inilah satu-satunya bentuk yang diterima penyimpanan. - Baris 13 (
JSON.parse(...)): string JSON dibaca dan dikembalikan menjadi array yang utuh — properti, angka, dan strukturnya kembali seperti semula. - Baris 19–21 (siklus tulis ulang): hasil
parseadalah array biasa, jadi ia bisa diubah (push) dan disimpan lagi denganstringify. Pola “baca → ubah → tulis ulang” inilah cara memperbarui data berstruktur. - Baris 25–26 (
sessionStorage): interface-nya identik dengan localStorage —setItem,getItem,removeItem, danclear()semuanya tersedia.
Event storage: Kabar dari Tab Lain #
Sifat localStorage yang dibagi antar tab punya kelanjutan yang sering luput: browser mengirim event storage pada tab lain setiap ada perubahan. Event ini membawa event.key, event.newValue, event.oldValue, dan event.url — cukup untuk mengetahui apa yang berubah dan dari halaman mana:
window.addEventListener("storage", (event) => {
if (event.key === "keranjang") {
console.log(`Keranjang berubah di ${event.url}:`, event.newValue);
}
});Dengan listener ini, dua tab yang menampilkan keranjang yang sama tetap sinkron: pengunjung yang menambah buku di tab pertama akan melihat tab kedua ikut memperbarui tampilannya. Dua detail menentukan pemakaiannya yang benar. Pertama, event hanya dikirim ke tab lain — tab yang melakukan perubahan tidak menerimanya sendiri, sehingga tab tersebut perlu memperbarui tampilannya langsung di alur kodenya. Kedua, event ini milik localStorage saja; sessionStorage yang terkurung dalam satu tab tidak mengirim kabar kepada siapa pun.
Ruang Lingkup: localStorage vs sessionStorage #
Kedua penyimpanan berbeda pada dua hal: berapa lama data bertahan dan siapa yang bisa melihatnya.
| Aspek | localStorage | sessionStorage |
|---|---|---|
| Masa simpan | permanen, bertahan sampai dihapus | hilang saat tab ditutup |
| Cakupan | seluruh tab dan jendela dengan origin sama | satu tab saja |
| Format nilai | string | string |
| Cocok untuk | preferensi, keranjang, token tema | status form per langkah, data sementara |
Dengan kata lain: preferensi tema Siti layak disimpan di localStorage agar bertahun-tahun kemudian masih terbaca, sedangkan draf isian form checkout cukup di sessionStorage karena tidak bermakna di luar kunjungan itu. Data yang ditulis satu tab tidak akan terlihat oleh tab lain pada sessionStorage; pada localStorage, perubahan langsung terlihat di semua tab origin yang sama.
Untuk kebutuhan penyimpanan berjumlat kilobita — preferensi, keranjang, draf isian — Web Storage adalah pilihan paling ringkas: tidak ada server, tidak ada library, cukup empat method yang sama untuk kedua penyimpanannya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
keranjang-json.js
Unduh berkas// keranjang-json.js — menyimpan array object dengan round-trip JSON
const keranjang = [
{ judul: "Kamus Mini Bahasa", jumlah: 1 },
{ judul: "Cerita di Sekitar Kita", jumlah: 2 },
];
// --- 1. object diubah menjadi string JSON sebelum disimpan ---
localStorage.setItem("keranjang", JSON.stringify(keranjang));
console.log("tersimpan :", localStorage.getItem("keranjang"));
// --- 2. string JSON dibaca lalu dikembalikan menjadi array ---
const tersimpan = JSON.parse(localStorage.getItem("keranjang"));
for (const buku of tersimpan) {
console.log(`${buku.judul} x${buku.jumlah}`);
}
// --- 3. array hasil parse adalah object biasa: bisa diubah lalu disimpan lagi ---
tersimpan.push({ judul: "Peta Jalur Sepeda", jumlah: 1 });
localStorage.setItem("keranjang", JSON.stringify(tersimpan));
const terbaru = JSON.parse(localStorage.getItem("keranjang"));
console.log("jumlah item:", terbaru.length);
// --- 4. sessionStorage memakai method yang sama ---
sessionStorage.setItem("langkah-checkout", "pengiriman");
console.log("langkah :", sessionStorage.getItem("langkah-checkout"));
preferensi-toko.js
Unduh berkas// preferensi-toko.js — menyimpan dan membaca preferensi di localStorage
// --- 1. menulis pasangan kunci-nilai ---
localStorage.setItem("nama-pengunjung", "Siti");
localStorage.setItem("tema", "gelap");
// --- 2. membaca nilai berdasarkan kuncinya ---
console.log("nama :", localStorage.getItem("nama-pengunjung"));
console.log("tema :", localStorage.getItem("tema"));
console.log("kupon:", localStorage.getItem("kupon")); // kunci tidak ada -> null
// --- 3. menimpa nilai lama dengan kunci yang sama ---
localStorage.setItem("tema", "terang");
console.log("tema baru:", localStorage.getItem("tema"));
// --- 4. menghapus satu kunci ---
localStorage.removeItem("nama-pengunjung");
console.log("nama setelah removeItem:", localStorage.getItem("nama-pengunjung"));