Kelas `JSON` di JavaScript
Artikel ini menjelaskan tentang kelas JSON di JavaScript.
Kami akan menjelaskan kelas JSON di JavaScript dengan contoh praktis.
YouTube Video
Kelas JSON di JavaScript
Objek JSON terutama memiliki dua metode. JSON.stringify() mengubah objek menjadi string JSON, dan JSON.parse() membuat objek dari string JSON. JSON adalah format pertukaran data yang hanya dapat merepresentasikan beberapa nilai JavaScript. Fungsi, undefined, Symbol, dan referensi sirkular tidak bisa dikonversi langsung ke JSON.
JSON.stringify()
Pertama, berikut adalah contoh dasar mengonversi objek menjadi string JSON.
1// Convert a JavaScript object to a JSON string.
2const obj = { name: "Alice", age: 30, active: true };
3const jsonString = JSON.stringify(obj);
4console.log(jsonString); // {"name":"Alice","age":30,"active":true}
- Kode ini adalah contoh paling dasar untuk mengonversi objek biasa menjadi string JSON.
JSON.stringifymengembalikan string secara sinkron.
Argumen kedua dari JSON.stringify (replacer)
Dengan menentukan replacer sebagai argumen kedua dari JSON.stringify, Anda dapat mengatur aturan konversi secara detail. Berikut adalah contoh menggunakan array untuk mempertahankan properti tertentu saja.
1// Use a replacer array to include only specific properties during stringification.
2const user = { id: 1, name: "Bob", password: "secret", role: "admin" };
3const safeJson = JSON.stringify(user, ["id", "name", "role"]);
4console.log(safeJson); // {"id":1,"name":"Bob","role":"admin"}
- Dalam contoh ini,
passworddiabaikan agar output log menjadi aman. Ini berguna saat Anda ingin menghapus informasi sensitif demi alasan keamanan.
Menggunakan replacer sebagai fungsi (untuk konversi dan penyaringan nilai)
Jika Anda ingin lebih fleksibel, Anda bisa menyediakan fungsi untuk memproses setiap kunci dan nilai. Di bawah ini adalah contoh menyimpan Date sebagai string ISO.
1// Use a replacer function to customize serialization.
2const data = { name: "Carol", joined: new Date("2020-01-01T12:00:00Z") };
3const jsonCustom = JSON.stringify(data, (key, value) => {
4 // Convert Date objects to ISO strings explicitly
5 if (this && this[key] instanceof Date) {
6 return this[key].toISOString();
7 }
8 return value;
9});
10console.log(jsonCustom); // {"name":"Carol","joined":"2020-01-01T12:00:00.000Z"}
- Dalam
replacerbertipe fungsi, kunci dan nilai diteruskan dan nilai yang dikembalikan akan digunakan pada JSON akhir.thismengacu pada objek induk, sehingga dapat digunakan juga untuk konversi bertingkat.
Dasar-dasar JSON.parse()
JSON.parse mengonversi string JSON kembali menjadi objek. Bungkus dengan try/catch agar Anda dapat menangani JSON tidak valid.
1// Parse a JSON string into an object and handle parsing errors.
2const jsonText = '{"title":"Example","count":42}';
3try {
4 const parsed = JSON.parse(jsonText);
5 console.log(parsed.title); // Example
6} catch (err) {
7 console.error("Invalid JSON:", err.message);
8}- Jika string tidak valid, akan terjadi pengecualian, jadi selalu sertakan penanganan pengecualian saat menangani sumber eksternal.
Restorasi khusus menggunakan reviver (contoh pemulihan Date)
Dengan menggunakan argumen kedua reviver dari JSON.parse, Anda dapat melakukan pemulihan nilai. Berikut adalah contoh mengonversi tanggal string yang disimpan kembali menjadi objek Date.
1// Use a reviver to turn ISO date strings back into Date objects.
2const jsonWithDate = '{"name":"Dana","joined":"2021-06-15T09:00:00.000Z"}';
3const obj = JSON.parse(jsonWithDate, (key, value) => {
4 // A simple check for ISO date-like strings
5 if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
6 return new Date(value);
7 }
8 return value;
9});
10console.log(obj.joined instanceof Date); // true
reviverdipanggil untuk setiap kunci, dan nilai yang dikembalikan akan digunakan di objek akhir. Silakan lakukan pengecekan format tanggal secara ketat sesuai aplikasi Anda.
Pretty-printing dan argumen space
Untuk menampilkan indentasi demi keterbacaan, berikan angka atau string sebagai argumen ketiga ke JSON.stringify.
1// Pretty-print an object with 2-space indentation for readability.
2const config = { host: "localhost", port: 3000, debug: true };
3const pretty = JSON.stringify(config, null, 2);
4console.log(pretty);
5/* {
6 "host": "localhost",
7 "port": 3000,
8 "debug": true
9} */- Untuk JSON yang akan dibaca oleh manusia, seperti log atau keluaran file konfigurasi, sangat membantu untuk menambahkan indentasi. Namun, harap perhatikan bahwa ini akan memperbesar ukuran.
Cara menangani referensi sirkular
JSON.stringify akan melemparkan TypeError jika ada referensi sirkular. Solusi umum adalah membuat replacer dengan menggunakan set seen untuk menghindari referensi sirkular.
1// Safely stringify objects that may contain circular references.
2function safeStringify(value) {
3 const seen = new WeakSet();
4 return JSON.stringify(value, (key, val) => {
5 if (val && typeof val === "object") {
6 if (seen.has(val)) return "[Circular]";
7 seen.add(val);
8 }
9 return val;
10 });
11}
12
13const a = { name: "A" };
14a.self = a;
15console.log(safeStringify(a)); // {"name":"A","self":"[Circular]"}
- Dengan menggunakan
WeakSet, Anda dapat mendeteksi referensi sirkular sambil menghindari kebocoran memori. Jika terjadi referensi sirkular, akan dikembalikan"[Circular]". Juga memungkinkan untuk menetapkan ID referensi sebagai ganti"[Circular]".
Serialisasi khusus dengan metode toJSON
Jika Anda mendefinisikan metode toJSON pada objek, JSON.stringify akan menggunakan nilai kembalian dari metode tersebut. Ini berguna saat Anda ingin menyisipkan aturan konversi untuk setiap tipe data.
1// Define toJSON on a class to customize its JSON representation.
2class Point {
3 constructor(x, y) {
4 this.x = x;
5 this.y = y;
6 }
7 toJSON() {
8 // This will be used by JSON.stringify
9 return { x: this.x, y: this.y, type: "Point" };
10 }
11}
12
13const p = new Point(10, 20);
14console.log(JSON.stringify(p)); // {"x":10,"y":20,"type":"Point"}
toJSONmemungkinkan Anda mendefinisikan aturan serialisasi di tingkat objek, sehingga lebih lokal dan intuitif dibandingkan dengan menggunakanreplacer.
Keterbatasan dan catatan mengenai JSON
Contoh yang tidak dapat diubah ke JSON adalah undefined, fungsi, Symbol, BigInt, dan referensi sirkular. Perhatikan juga presisi numerik (seperti bilangan bulat besar dan pembulatan titik mengambang IEEE).
1// Demonstrate values that can't be represented in JSON.
2const sample = {
3 a: undefined,
4 b: function () {},
5 c: Symbol("s"),
6 d: 9007199254740993n // BigInt (note: JSON.stringify will throw on BigInt)
7};
8// JSON.stringify will throw for BigInt and will drop undefined, functions, symbols in objects.
9try {
10 console.log(JSON.stringify(sample));
11} catch (err) {
12 console.error("Error during stringify:", err.message);
13}- Saat menangani
BigInt, konversikan ke string atau tentukan representasinya menggunakanreplaceratautoJSONkhusus.
Keamanan (saat menangani JSON yang tidak tepercaya)
JSON.parse itu sendiri aman dan dianggap lebih aman dibandingkan eval, tetapi berbahaya untuk mempercayai objek hasil parse dan menggunakannya langsung untuk mengakses properti atau kueri database. Selalu validasi dan periksa bahwa data sesuai dengan skema yang diharapkan.
1// Parse external JSON and validate expected properties before use.
2const external = '{"username":"eve","role":"user"}';
3const parsed = JSON.parse(external);
4if (typeof parsed.username === "string" && ["user","admin"].includes(parsed.role)) {
5 console.log("Safe to use parsed.username and parsed.role.");
6} else {
7 throw new Error("Invalid payload");
8}- Untuk validasi input (validasi skema), menggunakan library seperti
ajvsangat andal.
Pertimbangan kinerja
Sering menserialisasi dan mendeserialisasi objek besar akan membebani CPU dan memori. Jika perlu, pertimbangkan untuk hanya mengirim perbedaan saja, menggunakan format biner (seperti MessagePack), atau streaming (memproses data secara berurutan). Di lingkungan peramban, ada kasus di mana Anda dapat menggunakan structuredClone (untuk menyalin) atau objek yang dapat dipindahkan dalam postMessage.
Saran khusus (singkat)
Anda juga dapat mempertimbangkan poin-poin berikut:.
- Untuk log, hindari pretty-print dan gunakan JSON satu baris untuk mengurangi ukuran.
- Objek yang sering diserialisasi sebaiknya dibuat ringan sebelumnya, misalnya dengan menghapus properti yang tidak diperlukan.
- Gunakan
replaceruntuk meminimalkan penelusuran dan mengecualikan properti yang tidak diperlukan.
Contoh praktis: alur kirim/terima permintaan API
Akhirnya, berikut adalah urutan cara mengonversi objek dengan aman ke JSON untuk dikirim ke server dan mengembalikan tanggal dari respons yang diterima.
1// Prepare payload, stringify safely, send via fetch, and revive dates on response.
2async function sendUserUpdate(url, user) {
3 // Remove sensitive info before sending
4 const payload = JSON.stringify(user, (k, v) => (k === "password" ? undefined : v));
5 const res = await fetch(url, {
6 method: "POST",
7 headers: { "Content-Type": "application/json" },
8 body: payload
9 });
10
11 const text = await res.text();
12 // Reviver: convert ISO date strings back to Date
13 const data = JSON.parse(text, (key, value) => {
14 if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
15 return new Date(value);
16 }
17 return value;
18 });
19 return data;
20}- Dalam contoh ini,
passworddiabaikan sebelum dikirim, dan tanggal dipulihkan olehreviversetelah diterima. Dalam operasi nyata, Anda perlu menambahkan penanganan kesalahan dan pemrosesan timeout.
Ringkasan
Dengan menggunakan JSON.stringify() dan JSON.parse(), Anda dapat mengonversi antara objek dan string. Anda dapat menyesuaikan proses konversi menggunakan replacer dan reviver, dan jika Anda mengimplementasikan toJSON dalam sebuah kelas, Anda juga dapat mengontrol setiap objek secara individual. Referensi sirkular, BigInt, fungsi, dan sebagainya tidak dapat ditangani begitu saja, sehingga Anda perlu memprosesnya terlebih dahulu.
Selalu validasi input eksternal, dan pastikan informasi sensitif tidak termasuk dalam log atau komunikasi. Jika ukuran data besar, sebaiknya hindari pretty-print, pertimbangkan pengiriman diferensial, atau gunakan format biner.
Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.