Object keranjang belanja Budi hanya hidup di memori. Begitu ia ingin mengirim pesanan ke server, menyimpannya ke berkas, atau menampilkannya di log, object itu harus diubah menjadi teks — dan teks itulah yang nantinya dibaca ulang di tempat tujuan. Proses dua arah inilah inti serialization: JSON.stringify mengubah nilai JavaScript menjadi teks JSON, sedangkan JSON.parse mengubahnya kembali menjadi nilai.
Kedua arah ini terlihat sepele, tetapi menyimpan sejumlah keputusan penting: bagaimana bentuk teksnya dirapikan, bagaimana memilih kunci tertentu saja, dan apa yang terjadi pada nilai spesial seperti undefined, function, atau Date. Chapter ini membahas semuanya dengan satu skenario yang sama — keranjang Budi yang dikirim dan dibaca kembali.
Mengubah Object Menjadi Teks JSON #
Bentuk paling dasar JSON.stringify(nilai) menghasilkan teks JSON satu baris tanpa spasi:
const pesanan = { id: 7, item: ["pulpen", "buku"] };
console.log(JSON.stringify(pesanan));Output yang Dihasilkan:
{"id":7,"item":["pulpen","buku"]}Perhatikan perubahan yang terjadi: kunci id dan item kini berkutip ganda, tanda kutipnya adalah bagian dari teks, dan tidak ada spasi sama sekali. Hasil stringify selalu berupa string — kalau dicetak dengan console.log, kita melihat teks, bukan object. Teks satu baris seperti ini efisien untuk dikirim lewat jaringan, tetapi sulit dibaca manusia. Untuk itu stringify menerima opsi tambahan, yang kita bahas lewat berkas berikut.
Argumen pertama stringify tidak harus object. Array, string, number, bahkan null semuanya bisa diserialisasi — polanya sama dengan yang kita lihat di chapter sebelumnya ketika JSON.parse menerima bentuk-bentuk sederhana:
console.log(JSON.stringify(["a", "b"]));
console.log(JSON.stringify("halo"));Output yang Dihasilkan:
["a","b"]
"halo"Array menjadi teks array JSON, dan string menjadi teks JSON yang isinya string — lengkap dengan kutip gandanya. Inilah tanda bahwa stringify bekerja pada nilai apa pun, bukan hanya object.
Indentasi, Replacer, dan Reviver #
Berkas berikut memakai JSON.stringify dengan tiga variasi — indentasi, replacer array, dan replacer function — lalu membaca balasan server dengan JSON.parse ber-reviver:
// kirim-keranjang.js — object JS menjadi teks JSON, lalu dibaca kembali
const keranjang = {
pembeli: "Budi",
total: 85000,
metode: "transfer",
promo: "HEMAT20",
dibayar: new Date("2026-08-17T09:30:00Z"),
};
// --- 1. stringify dengan indentasi ---
const teksTerkirim = JSON.stringify(keranjang, null, 2);
console.log(teksTerkirim);
// --- 2. replacer array: hanya kunci terpilih ---
console.log(JSON.stringify(keranjang, ["pembeli", "total"]));
// --- 3. replacer function: ubah semua string jadi huruf besar ---
const rapi = JSON.stringify(keranjang, (kunci, nilai) => {
if (typeof nilai === "string" && kunci !== "") {
return nilai.toUpperCase();
}
return nilai;
});
console.log(rapi);
// --- 4. parse dengan reviver: teks tanggal kembali jadi Date ---
const balasan = '{"pembeli":"Budi","status":"LUNAS","dibayar":"2026-08-17T09:30:00.000Z"}';
const diterima = JSON.parse(balasan, (kunci, nilai) => {
if (kunci === "dibayar") return new Date(nilai);
return nilai;
});
console.log(diterima.dibayar instanceof Date);
console.log(diterima.dibayar.toISOString());
console.log(diterima.status);Output yang Dihasilkan:
{
"pembeli": "Budi",
"total": 85000,
"metode": "transfer",
"promo": "HEMAT20",
"dibayar": "2026-08-17T09:30:00.000Z"
}
{"pembeli":"Budi","total":85000}
{"pembeli":"BUDI","total":85000,"metode":"TRANSFER","promo":"HEMAT20","dibayar":"2026-08-17T09:30:00.000Z"}
true
2026-08-17T09:30:00.000Z
LUNASMari kita telaah baris-baris pentingnya:
- Baris 11 (
JSON.stringify(keranjang, null, 2)): argumen kedua adalah replacer (di sininull, artinya tidak menyaring apa pun), argumen ketiga adalah indentasi. Angka2membuat setiap tingkat menjorok dua spasi — hasilnya nyaman dibaca, cocok untuk log dan berkas konfigurasi. - Baris 15 (replacer array): bila replacer berupa array, hanya kunci yang tercantum yang ikut. Hasilnya hanya
pembelidantotal, dengan urutan mengikuti urutan array — berguna saat respons harus ramping. - Baris 18–23 (replacer function): bila replacer berupa function, setiap pasangan kunci-nilai melewatinya lebih dulu.
stringifybahkan memanggilnya lebih dulu dengan kunci""untuk nilai akarnya — karena itu ada syaratkunci !== ""agar string akar tidak ikut diproses. Semua string milik object berubah menjadi huruf besar, sedangkandibayar(objectDate, bukan string) dibiarkan. - Baris 28–31 (reviver):
JSON.parsemenerima function kedua bernama reviver. Reviver bekerja dari nilai terdalam ke luar — item array diolah lebih dulu, baru object pembungkusnya — sehingga bila kunci bernamadibayar, teks ISO diubah kembali menjadi objectDatedengannew Date(nilai), dan sisanya dikembalikan apa adanya. Urutan ini membuat pola “ubah field tertentu saat dibaca” mudah ditulis: cukup periksa nama kuncinya. - Baris 32–34 (pemeriksaan hasil):
diterima.dibayar instanceof Datemenjawabtrue— tanggalnya benar-benar kembali sebagaiDate, dantoISOString()membuktikan isinya sama persis dengan teks aslinya.
toJSON: Menentukan Bentuk Kiriman Sendiri #
stringify tidak memeriksa kunci saja; ia juga memeriksa nilai. Bila sebuah nilai punya method toJSON, stringify memanggil method itu dan menggunakan hasilnya sebagai pengganti nilai aslinya. Method ini membuat object bisa menentukan sendiri bentuk JSON-nya:
const tagihan = {
nomor: "INV-092",
jatuhTempo: new Date("2026-08-31T00:00:00Z"),
toJSON() {
return { nomor: this.nomor, jatuhTempo: this.jatuhTempo.toISOString() };
},
};
console.log(JSON.stringify(tagihan));Output yang Dihasilkan:
{"nomor":"INV-092","jatuhTempo":"2026-08-31T00:00:00.000Z"}Class Date bawaan JavaScript sudah memiliki toJSON — itulah sebabnya dibayar pada berkas utama otomatis berubah menjadi teks ISO tanpa kita melakukan apa pun. Dengan menulis toJSON sendiri, pola yang sama bisa dipakai untuk object buatan kita, misalnya menyembunyikan kunci internal atau menyeragamkan format sebelum dikirim.
Urutan Kunci pada Hasil stringify #
JSON tidak menjamin urutan kunci secara formal, tetapi stringify yang kita pakai mengikuti aturan yang stabil dan perlu diketahui: kunci string dipertahankan sesuai urutan kemunculannya, sedangkan kunci berupa angka (kunci array yang ditulis dalam object) selalu maju lebih dulu dan diurutkan menaik:
console.log(JSON.stringify({ b: 1, a: 2 }));
console.log(JSON.stringify({ 2: "x", 1: "y" }));Output yang Dihasilkan:
{"b":1,"a":2}
{"1":"y","2":"x"}Object pertama mempertahankan urutan b lalu a — persis seperti saat ditulis. Object kedua justru mencetak 1 sebelum 2, meskipun kita menulis 2 lebih dulu: kunci yang terlihat seperti angka selalu dikumpulkan di depan dalam urutan menaik. Untuk data pertukaran biasa ini tidak berpengaruh — pihak penerima membaca kunci berdasarkan namanya, bukan posisinya — tetapi urutan ini terasa saat membandingkan dua teks JSON yang dihasilkan di waktu berbeda.
Jebakan Nilai Khusus #
Bagian yang paling sering mengejutkan pemula: tidak semua nilai JavaScript punya padanan JSON. Mari kita uji sekaligus:
const prihal = {
catatan: undefined,
sapa() { return "halo"; },
batas: NaN,
takHingga: Infinity,
tanggal: new Date("2026-08-17T09:30:00Z"),
};
console.log(JSON.stringify(prihal));
console.log(JSON.stringify([undefined, null, 1]));Output yang Dihasilkan:
{"batas":null,"takHingga":null,"tanggal":"2026-08-17T09:30:00.000Z"}
[null,null,1]Hasilnya memperlihatkan tiga aturan sekaligus:
- Kunci
catatandansapa:undefineddan function tidak ada di JSON, sehingga keduanya dihilangkan dari hasil. Tidak ada peringatan — data yang terkirim memang lebih sedikit dari yang kita tulis. NaNdanInfinity: keduanya adalah nilai number yang sah di JavaScript tetapi tidak dikenal JSON, sehingga ditulis sebagainull.- Elemen array
undefined: di dalam array, posisi harus tetap ada agar urutan tidak bergeser, makaundefinedditulisnull— berbeda dengan di object yang kuncinya dihilangkan begitu saja. tanggal: objectDateberubah menjadi string ISO. Di sisi penerima, hasilnya string biasa — bukanDate— sampai kita mengembalikannya dengan reviver seperti pada berkas utama.
Setelah menguasai kedua arah JSON, satu pertanyaan tersisa: bagaimana bila yang kita butuhkan bukan teks untuk dikirim, melainkan salinan data untuk dipakai sendiri di dalam program — lengkap dengan Map, Set, dan Date yang utuh? Untuk kebutuhan itu, chapter berikutnya memperkenalkan structuredClone.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
kirim-keranjang.js
Unduh berkas// kirim-keranjang.js — object JS menjadi teks JSON, lalu dibaca kembali
const keranjang = {
pembeli: "Budi",
total: 85000,
metode: "transfer",
promo: "HEMAT20",
dibayar: new Date("2026-08-17T09:30:00Z"),
};
// --- 1. stringify dengan indentasi ---
const teksTerkirim = JSON.stringify(keranjang, null, 2);
console.log(teksTerkirim);
// --- 2. replacer array: hanya kunci terpilih ---
console.log(JSON.stringify(keranjang, ["pembeli", "total"]));
// --- 3. replacer function: ubah semua string jadi huruf besar ---
const rapi = JSON.stringify(keranjang, (kunci, nilai) => {
if (typeof nilai === "string" && kunci !== "") {
return nilai.toUpperCase();
}
return nilai;
});
console.log(rapi);
// --- 4. parse dengan reviver: teks tanggal kembali jadi Date ---
const balasan = '{"pembeli":"Budi","status":"LUNAS","dibayar":"2026-08-17T09:30:00.000Z"}';
const diterima = JSON.parse(balasan, (kunci, nilai) => {
if (kunci === "dibayar") return new Date(nilai);
return nilai;
});
console.log(diterima.dibayar instanceof Date);
console.log(diterima.dibayar.toISOString());
console.log(diterima.status);