Begitu programmu perlu berkomunikasi dengan sesuatu di luar dirinya — server, file, atau aplikasi lain — kamu langsung ketemu masalah yang sama: objek JavaScript itu hidup di dalam memori dan nggak bisa dikirim lewat kabel jaringan begitu saja. Kamu butuh cara untuk mengubah objek tadi menjadi teks biasa saat hendak dikirim, lalu mengubah teksnya kembali jadi objek saat diterima. Format teks itulah yang disebut JSON, dan inilah “bahasa” yang dipakai hampir seluruh web untuk memindahkan data.
Kamu sudah tahu cara membuat array dan objek. Nah, JSON itu wujud dari struktur-struktur tadi setelah dipipihkan menjadi sebuah string yang bisa kamu kirim atau simpan. Di artikel ini kamu bakal belajar apa sebenarnya JSON itu, dua fungsi yang mengubah objek menjadi JSON dan sebaliknya, serta beberapa aturan tak terduga yang sering bikin orang kepleset di urusan date, undefined, dan input yang nggak valid.
Apa itu JSON?
JSON adalah singkatan dari JavaScript Object Notation. Ini format teks yang ringan untuk merepresentasikan data terstruktur — dan meski namanya membawa kata “JavaScript”, sekarang penggunaannya jauh melampaui itu. Python, PHP, Go, aplikasi mobile, database: hampir semuanya bisa membaca dan menulis JSON. JSON jadi cara default antar-layanan bertukar data justru karena bentuknya sederhana dan gampang dibaca, baik oleh manusia maupun mesin.
Ini contoh kecil JSON:
{
"name": "John Doe",
"age": 28,
"isMember": true,
"roles": ["editor", "admin"]
}
Kalau bentuknya kelihatan mirip banget sama objek JavaScript, ya memang itulah intinya — sintaks JSON memang dipinjam dari penulisan objek di JavaScript. Tapi “mirip banget” itu beda dengan “sama persis”, dan perbedaannya justru yang penting.
JSON itu string, bukan objek
Ini gagasan paling penting di seluruh topik ini, jadi langsung kita tegaskan: JSON itu teks. Blok di atas tadi bukan objek JavaScript — itu sebuah string yang kebetulan ditulis dengan gaya JSON. Kamu nggak bisa memanggil .name di atasnya atau melakukan perulangan padanya. Selama belum diubah menjadi objek beneran, dia cuma deretan karakter.
Jadi pada praktiknya, kamu selalu melakukan salah satu dari dua hal ini:
- Serialisasi (sering disebut juga stringify): mengubah objek JavaScript yang hidup menjadi string JSON, siap dikirim atau disimpan.
- Parsing: mengubah string JSON yang kamu terima kembali menjadi objek JavaScript yang bisa langsung dipakai.
JavaScript membekalimu tepat satu fungsi bawaan untuk masing-masing arah, dan keduanya menempel pada objek global bernama JSON.
JSON.stringify: dari objek ke JSON
JSON.stringify() menerima sebuah nilai JavaScript dan mengembalikan versi string JSON-nya:
const pengguna = {
name: "John Doe",
age: 28,
isMember: true,
};
const json = JSON.stringify(pengguna);
console.log(json);
// '{"name":"John Doe","age":28,"isMember":true}'
console.log(typeof json);
// "string"
Perhatikan hasilnya jadi satu baris yang padat, dan typeof json membuktikan bahwa itu memang string. String inilah yang nantinya kamu taruh di body sebuah permintaan jaringan atau kamu simpan ke file. Perhatikan juga setiap key sekarang dibungkus tanda kutip ganda — ini aturan baku di JSON, yang nanti kita bahas lagi.
Merapikan output dengan indentasi
Secara default stringify memberimu satu baris padat tadi, yang memang efisien buat mesin tapi capek dibaca manusia. Argumen ketiga mengatur indentasi — kasih sebuah angka, dan tiap tingkat akan dijorokkan sebanyak angka itu (dalam spasi):
const pengguna = { name: "John Doe", age: 28, roles: ["editor", "admin"] };
console.log(JSON.stringify(pengguna, null, 2));
/*
{
"name": "John Doe",
"age": 28,
"roles": [
"editor",
"admin"
]
}
*/
null di tengah itu adalah replacer (sebentar lagi kita bahas); angka 2 artinya “jorokkan dengan dua spasi.” Ini murni demi enaknya dibaca mata manusia — saat kamu lagi mencetak JSON untuk debugging, JSON.stringify(value, null, 2) termasuk satu baris kode paling berguna yang sebaiknya kamu hafal.
Membaca JSON yang berantakan
Saat kamu menerima JSON panjang dalam satu baris dan perlu benar-benar membacanya, tempelkan saja ke sebuah JSON formatter biar dirapikan dan diberi warna. Kami menyediakan JSON formatter gratis yang merapikan sekaligus memvalidasi dalam satu langkah — sangat membantu ketika sebuah API menyerahkan tembok teks tanpa jeda dan kamu lagi mencari satu field yang salah.
Argumen replacer
Argumen kedua tadi — si replacer — memberimu kendali atas property mana saja yang ikut masuk ke output. Bentuk yang paling umum adalah sebuah array berisi nama key yang ingin kamu pertahankan:
const pengguna = {
name: "John Doe",
age: 28,
password: "rahasia123",
};
// Hanya sertakan name dan age — buang password
console.log(JSON.stringify(pengguna, ["name", "age"]));
// '{"name":"John Doe","age":28}'
Kamu juga bisa mengoper sebuah fungsi sebagai replacer untuk mengubah nilai di tengah jalan, tapi bentuk array ini sudah cukup untuk sebagian besar kebutuhan nyata — misalnya memastikan field sensitif tidak ikut keluar dari programmu tanpa sengaja.
JSON.parse: dari JSON ke objek
JSON.parse() adalah kebalikannya: kasih dia sebuah string JSON, dan dia mengembalikan nilai JavaScript beneran yang siap kamu olah:
const json = '{"name":"John Doe","age":28,"isMember":true}';
const pengguna = JSON.parse(json);
console.log(pengguna.name); // "John Doe"
console.log(pengguna.age + 1); // 29
console.log(typeof pengguna); // "object"
Setelah di-parse, pengguna adalah objek biasa — kamu bisa membaca pengguna.name dengan dot notation, melakukan operasi hitung pada pengguna.age, dan melakukan perulangan padanya seperti objek lainnya. Langkah inilah yang terjadi tiap kali kodemu menerima data: sebuah respons datang berupa string JSON, kamu parse, lalu kamu sudah punya objek yang siap dipakai.
Array pun masuk persis dengan cara yang sama:
const json = '[{"name":"Keyboard","price":250000},{"name":"Mouse","price":120000}]';
const produk = JSON.parse(json);
console.log(produk.length); // 2
console.log(produk[0].name); // "Keyboard"
Bentuk array-berisi-objek itu adalah hal yang paling sering dikembalikan sebuah API — yaitu sebuah daftar berisi catatan — dan parsing langsung mengubahnya menjadi array yang bisa kamu susuri satu per satu.
Aturan ketat JSON
JSON memang kelihatan seperti JavaScript, tapi dia format yang lebih ketat dan lebih kecil. Langgar satu aturan, dan JSON.parse bakal melempar error alih-alih menebak-nebak maksudmu. Aturan yang layak kamu tanamkan kuat-kuat:
- Key harus pakai tanda kutip ganda.
{"name": "x"}valid;{name: "x"}tidak. Kutip tunggal juga tidak boleh. - String harus pakai tanda kutip ganda.
'halo'bukan JSON yang valid; harus"halo". - Tidak boleh ada koma di akhir.
[1, 2, 3,]boleh di array JavaScript, tapi tidak valid di JSON. - Tidak boleh ada komentar. Kamu nggak bisa menaruh
//atau/* */di dalam JSON. - Tidak boleh ada fungsi, dan tidak boleh
undefined. JSON hanya membawa data: string, number, boolean,null, array, dan objek.
// JSON VALID
'{"active": true, "count": 3, "tags": ["a", "b"]}'
// JSON TIDAK VALID — kutip tunggal, key tanpa kutip, koma di akhir
"{name: 'John', age: 28,}"
JSON.parse melempar error untuk input yang rusak
Kalau kamu memberi JSON.parse sebuah string yang bukan JSON valid, dia nggak mengembalikan null atau undefined — dia melempar SyntaxError dan menghentikan kodemu di tempat. Respons jaringan yang terpotong, string kosong, atau koma yang nyasar saja sudah cukup memicunya. Karena kamu jarang benar-benar mengendalikan teks persis yang kamu terima, perlakukan parsing sebagai sesuatu yang bisa gagal, lalu bungkus dengan pengaman. Caranya kita lihat sebentar lagi.
Parsing yang aman dengan try…catch
Karena JSON.parse bisa melempar error, kamu membungkusnya dalam blok try...catch setiap kali inputnya datang dari tempat yang nggak sepenuhnya kamu kendalikan — server, input pengguna, atau file. Dengan begitu, respons yang rusak ditangani dengan anggun alih-alih membuat seluruh halaman crash:
function parseAman(teks) {
try {
return JSON.parse(teks);
} catch (err) {
console.error("JSON tidak valid:", err.message);
return null;
}
}
console.log(parseAman('{"ok": true}')); // { ok: true }
console.log(parseAman("bukan json")); // null (sekaligus mencatat error-nya)
Sekarang si pemanggil tinggal mengecek apakah dia menerima null, bukannya seluruh skrip meledak gara-gara satu respons yang cacat. Kalau try...catch masih asing buatmu, artikel penanganan error mengupasnya secara rinci — dan parsing JSON ini termasuk salah satu tempat paling pas untuk memakainya.
Jebakan: date, undefined, dan tipe yang hilang
JSON cuma bisa merepresentasikan segelintir tipe dasar. Apa pun di luar himpunan itu bakal dikonversi atau diam-diam dibuang saat keluar, dan inilah yang melahirkan beberapa kejutan klasik.
undefined dan fungsi menghilang
Saat kamu men-stringify sebuah objek, property mana pun yang nilainya undefined atau berupa fungsi akan langsung dihilangkan dari output — tanpa error, dia cuma lenyap:
const data = {
name: "John Doe",
nickname: undefined,
greet: function () { return "hai"; },
};
console.log(JSON.stringify(data));
// '{"name":"John Doe"}' — nickname dan greet hilang
Date berubah menjadi string
Objek Date nggak selamat melewati perjalanan bolak-balik. stringify mengubahnya menjadi string ISO, dan parse nggak punya cara untuk tahu bahwa dulunya itu sebuah date — yang kamu terima kembali cuma string biasa:
const acara = { title: "Launch", when: new Date("2026-08-09") };
const json = JSON.stringify(acara);
console.log(json);
// '{"title":"Launch","when":"2026-08-09T00:00:00.000Z"}'
const dipulihkan = JSON.parse(json);
console.log(typeof dipulihkan.when); // "string", bukan Date!
Jadi setelah parsing, kalau kamu butuh Date beneran, kamu harus membangunnya ulang sendiri: new Date(dipulihkan.when). Hal ini menjebak banyak orang — mereka men-stringify sebuah date, mem-parse-nya kembali, lalu bingung kenapa method-method date tiba-tiba nggak berfungsi.
JSON hanya membawa data polos
Model berpikir yang menjauhkanmu dari masalah: JSON itu format data, bukan potret JavaScript. Dia mengenal string, number, boolean, null, array, dan objek — selain itu tidak ada. Date, fungsi, undefined, Map, Set, instance class — tidak ada satu pun yang selamat utuh. Kalau ada nilai yang kembali “salah” setelah perjalanan bolak-balik, hampir selalu inilah sebabnya, dan solusinya adalah membangun ulang tipe yang lebih kaya itu sendiri setelah parsing.
Deep-clone pakai JSON (dan batasannya)
Ada satu trik populer yang muncul dari semua ini: stringify sebuah objek lalu langsung parse balik, dan kamu mendapatkan salinan yang benar-benar baru serta sepenuhnya mandiri — sebuah deep clone:
const asli = { user: { name: "John Doe" }, tags: ["a", "b"] };
const salinan = JSON.parse(JSON.stringify(asli));
salinan.user.name = "Jane Doe";
console.log(asli.user.name); // "John Doe" — yang asli tidak tersentuh
Mengubah salinannya nggak berpengaruh ke yang asli, bahkan untuk objek yang bersarang — sesuatu yang nggak bisa dijamin oleh spread sederhana { ...asli }. Trik ini cepat dan jalan untuk data polos. Tapi ingat semua jebakan di atas: trik ini diam-diam menghilangkan date, undefined, dan fungsi. Untuk data yang aman-JSON ya nggak masalah; untuk apa pun yang lebih kaya, JavaScript modern punya structuredClone() bawaan yang sanggup menangani date dan lainnya, dan itu pilihan yang lebih baik kalau memang tersedia.
Perjalanan bolak-balik yang realistis
Coba kita satukan kedua arah tadi seperti yang benar-benar bakal kamu pakai — bangun sebuah objek, serialisasi untuk dikirim, lalu parse sebuah respons:
// 1. Kamu punya objek yang hidup
const pesanan = {
customer: "Jane Doe",
items: [
{ name: "Keyboard", qty: 1 },
{ name: "Mouse", qty: 2 },
],
};
// 2. Serialisasi untuk dikirim ke server
const payload = JSON.stringify(pesanan);
// '{"customer":"Jane Doe","items":[{"name":"Keyboard","qty":1},...]}'
// 3. Sebuah respons datang berupa string JSON
const teksRespons = '{"orderId":7421,"status":"confirmed"}';
// 4. Parse untuk memakai datanya
const hasil = JSON.parse(teksRespons);
console.log(hasil.status); // "confirmed"
Alur keluar-dan-kembali itu — stringify untuk mengirim, parse untuk menerima — adalah irama sehari-hari saat bekerja dengan data di web. Begitu nanti kamu mulai memakai Fetch API untuk berkomunikasi dengan server beneran, persis inilah tarian yang kamu lakukan di tiap permintaan.
Penutup
JSON adalah cara data terstruktur berpindah antar program, dan dua fungsi sudah mencakup seluruh pekerjaannya:
- JSON adalah format teks untuk data terstruktur — dipinjam dari sintaks JavaScript, tapi dipakai hampir semua bahasa dan layanan. Sebuah string JSON itu teks, bukan objek yang langsung bisa dipakai, sampai kamu mem-parse-nya.
JSON.stringify(value)menyerialkan objek menjadi string JSON. Oper(value, null, 2)untuk merapikannya dengan indentasi.JSON.parse(text)mengubah string JSON kembali menjadi nilai JavaScript beneran yang bisa kamu pakai.- JSON punya aturan ketat: key dan string pakai kutip ganda, tanpa koma di akhir, tanpa komentar, tanpa fungsi atau
undefined. Langgar satu,parsebakal melempar error — jadi bungkus input yang tak tepercaya dengantry...catch. - Dia cuma membawa data polos. Date berubah jadi string, dan
undefined/fungsi dibuang. Bangun ulang tipe yang lebih kaya itu sendiri setelah parsing. JSON.parse(JSON.stringify(obj))adalah deep clone cepat untuk data yang aman-JSON, dengan batasan yang sama tadi.
Setelah menguasai serialisasi dan parsing, kamu siap untuk langkah berikutnya: benar-benar mengambil data dari sebuah server. JSON adalah format saat data itu tiba, jadi semua yang kamu pelajari di sini langsung nyambung ke pekerjaan dengan Promise dan Fetch API, yang bakal kita bahas selanjutnya.