Budi mengelola toko buku daring. Suatu pagi, penerbit mitranya mengirim data katalog dalam bentuk berkas teks berformat JSON: daftar judul, penulis, harga, dan status ketersediaan. Budi mencoba menempelkan isi berkas itu langsung ke dalam kode JavaScript — sebagian berhasil dibaca, sebagian membuat program berhenti dengan pesan SyntaxError. Ternyata teks yang tampak “sama dengan object JavaScript” belum tentu sah sebagai JSON.
JSON (JavaScript Object Notation) adalah format teks untuk pertukaran data. Meskipun namanya berasal dari JavaScript, JSON dipakai hampir semua bahasa pemrograman: server, aplikasi mobile, hingga berkas konfigurasi. Karena harus dibaca berbagai bahasa, aturan sintaks JSON jauh lebih ketat daripada object literal JavaScript. Chapter ini membahas aturan itu satu per satu, lalu memeriksa JSON dengan JSON.parse untuk melihat sendiri bentuk mana yang diterima dan mana yang ditolak.
Aturan Sintaks JSON #
JSON hanya mengenali enam jenis nilai: string, number, boolean (true/false), null, array, dan object. Di luar itu tidak ada. Perbedaan paling sering menjebak adalah perbandingannya dengan object literal yang kita tulis di kode JavaScript:
| Aspek | Object literal (kode JS) | JSON (teks data) |
|---|---|---|
| Kunci object | boleh tanpa kutip | wajib berkutip ganda |
| String | kutip tunggal, ganda, atau template literal | hanya kutip ganda |
| Komentar | boleh | tidak ada |
Koma terakhir sebelum } atau ] | boleh | galat |
Function, undefined | sah sebagai nilai | tidak ada |
NaN, Infinity | sah sebagai nilai number | tidak ada |
Dua aturan pertama yang paling sering membuat JSON ditolak. Teks {'judul': 'Cerita Kopi'} terlihat wajar bagi mata yang terbiasa membaca JavaScript, tetapi JSON menuntut kunci dan string berkutip ganda. Begitu pula koma menggantung (trailing comma) — sah di kode JS modern, ditolak di JSON.
Aturan angka juga lebih sempit daripada number JavaScript. JSON menerima bilangan desimal biasa dengan tanda minus, bagian pecahan, dan bentuk eksponensial (2.5e3 sah). Yang tidak diterima: nol di depan seperti 007, tanda heksadesimal 0x, serta NaN dan Infinity — ketiganya sah di kode JavaScript tetapi bukan angka JSON. Bila data berisi nilai-nilai itu, yang terkirim nanti bukan angkanya (chapter berikutnya memperlihatkan apa penggantinya).
Memeriksa JSON dengan JSON.parse #
Aturan di atas berlaku begitu kita mempraktikkannya: JSON.parse(teks) membaca teks JSON dan mengembalikan nilai JavaScript yang setara. Bila teksnya tidak sah, JSON.parse melempar SyntaxError. Berkas berikut menguji satu teks JSON valid dan empat teks rusak — masing-masing melanggar satu aturan:
// uji-json.js — membedakan JSON yang valid dan tidak valid
const teksValid = `{
"judul": "Cerita Kopi Nusantara",
"penulis": "Rina Kartika",
"cetakan": 3,
"tersedia": true,
"nilaiUlasan": 4.5,
"tag": ["sastra", "indonesia"]
}`;
const teksSalah = [
"{'judul': 'Cerita Kopi'}", // kutip satu
'{"judul": "Cerita Kopi",}', // koma menggantung
'{ // kategori fiksi\n "judul": "Cerita Kopi"}', // komentar
'{"judul": undefined}', // undefined
];
console.log(JSON.parse(teksValid));
for (const teks of teksSalah) {
try {
JSON.parse(teks);
} catch (galat) {
console.log(galat.constructor.name + ": " + galat.message);
}
}Output yang Dihasilkan:
{
judul: 'Cerita Kopi Nusantara',
penulis: 'Rina Kartika',
cetakan: 3,
tersedia: true,
nilaiUlasan: 4.5,
tag: [ 'sastra', 'indonesia' ]
}
SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
SyntaxError: Expected double-quoted property name in JSON at position 24 (line 1 column 25)
SyntaxError: Expected property name or '}' in JSON at position 2 (line 1 column 3)
SyntaxError: Unexpected token 'u', "{"judul": undefined}" is not valid JSONMari kita telaah baris-baris pentingnya:
- Baris 2–9 (
const teksValid = ...): teks JSON ditulis dalam template literal agar kutip gandanya tidak perlu di-escape. Perhatikan seluruh kunci berkutip ganda, tidak ada komentar, dan tidak ada koma setelah anggota terakhir — inilah syarat JSON yang sah. - Baris 11–16 (
const teksSalah = [...]): empat teks rusak dikumpulkan dalam array, masing-masing melanggar satu aturan: kutip satu, koma menggantung, komentar, dan nilaiundefined. - Baris 18 (
JSON.parse(teksValid)): teks yang sah diubah menjadi object JavaScript. Hasilnya dicetak utuh:cetakankembali sebagai number,tersediasebagai boolean, dantagsebagai array — tipe JS asli, bukan lagi teks. - Baris 20–25 (loop
for...ofdengantry...catch): setiap teks rusak dicoba di-parse. Kegagalan ditangkap, lalu nama class galat dan pesannya dicetak. Pemisahan pesan seperti ini memudahkan kita mengenali pola galat JSON saat mengerjakan proyek nyata.
Perhatikan juga pesan galatnya. Untuk kutip satu, parser berhenti pada position 1 karena karakter ' memang bukan awal kunci yang sah. Untuk koma menggantung, parser mengira setelah koma datang kunci baru — lalu protes kunci itu tidak berkutip ganda. Pesan-pesan ini menjawab “di mana” dan “apa”, meskipun kadang perlu ditafsirkan sedikit.
JSON Tidak Harus Berupa Object #
Kesalahpahaman lain yang lazim: dokumen JSON harus dimulai {. Sebenarnya keenam jenis nilai JSON boleh menjadi isi utama dokumen. Tiga baris berikut semuanya JSON yang sah:
console.log(JSON.parse("42"), JSON.parse('"halo"'), JSON.parse("null"));Output yang Dihasilkan:
42 halo nullHasilnya adalah number 42, string halo, dan null — tiga nilai JavaScript biasa. Catatan pentingnya: bila teks JSON berupa string, teks itu tetap sebuah data berkutip ganda di dalam JSON. Pada contoh di atas kita membungkusnya dengan kutip satu ('"halo"') agar tidak bentrok. Bentuk seperti ini jarang dipakai dalam aplikasi, tetapi berguna untuk memahami bahwa JSON adalah aturan tentang teks, bukan tentang object.
Di Mana JSON Kita Temui #
Karena ringkas dan lintas bahasa, JSON mengisi hampir semua celah pertukaran data yang kita sentuh sehari-hari:
- badan respons API — mayoritas API web mengirim data dalam JSON; nanti kita memparse-nya sebelum dipakai;
- berkas konfigurasi dan data — dari
package.jsonproyek Node sampai berkas ekspor-impor aplikasi; - log terstruktur — aplikasi server mencatat kejadian dalam JSON agar mudah dicari mesin;
- pesan antar program — antrian pesan dan layanan latar saling mengirim JSON.
Semua penggunaan itu bertumpu pada dua operasi yang sama: membaca JSON menjadi nilai, dan menulis nilai menjadi JSON. Operasi pertama sudah kita latih di atas; operasi keduanya — lengkap dengan opsi indentasi, penyaring kunci, dan jebakan nilainya — adalah bahasan penuh chapter berikutnya.
Membedakan Object Literal dan JSON #
Karena keduanya mirip, kita perlu kebiasaan yang tegas: lihat konteksnya. Kode di berkas .js mengikuti aturan JavaScript; data di berkas .json atau isi badan (body) respons HTTP mengikuti aturan JSON. JSON yang sah selalu bisa dibaca sebagai object literal JavaScript — tetapi kebalikannya tidak berlaku, karena object literal boleh memuat hal yang tidak dikenal JSON: komentar, kunci tanpa kutip, undefined, dan function.
Sampai di sini kita bisa membaca JSON, mengenali bentuk yang ditolak, dan tahu di mana JSON dipakai. Kebalikan dari proses ini — mengubah object JavaScript menjadi teks JSON agar bisa dikirim — adalah bahasan chapter berikutnya, bersama JSON.stringify dan jebakan-jebakan nilainya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
uji-json.js
Unduh berkas// uji-json.js — membedakan JSON yang valid dan tidak valid
const teksValid = `{
"judul": "Cerita Kopi Nusantara",
"penulis": "Rina Kartika",
"cetakan": 3,
"tersedia": true,
"nilaiUlasan": 4.5,
"tag": ["sastra", "indonesia"]
}`;
const teksSalah = [
"{'judul': 'Cerita Kopi'}", // kutip satu
'{"judul": "Cerita Kopi",}', // koma menggantung
'{ // kategori fiksi\n "judul": "Cerita Kopi"}', // komentar
'{"judul": undefined}', // undefined
];
console.log(JSON.parse(teksValid));
for (const teks of teksSalah) {
try {
JSON.parse(teks);
} catch (galat) {
console.log(galat.constructor.name + ": " + galat.message);
}
}