Kelas `JSON` dalam JavaScript
Artikel ini menerangkan tentang kelas JSON dalam JavaScript.
Kami akan menerangkan kelas JSON dalam JavaScript dengan contoh praktikal.
YouTube Video
Kelas JSON dalam JavaScript
Objek JSON terutamanya mempunyai dua kaedah. JSON.stringify() menukar objek kepada rentetan JSON, dan JSON.parse() mencipta objek daripada rentetan JSON. JSON ialah format pertukaran data yang hanya boleh mewakili sebahagian nilai JavaScript. Fungsi, undefined, Symbol, dan rujukan bulat tidak boleh ditukar secara langsung kepada JSON.
JSON.stringify()
Pertama sekali, berikut adalah contoh asas menukar objek kepada rentetan 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}
- Kod ini adalah contoh paling asas untuk menukar objek biasa kepada rentetan JSON.
JSON.stringifymengembalikan rentetan secara segerak.
Argumen kedua bagi JSON.stringify (replacer)
Dengan menentukan replacer, argumen kedua untuk JSON.stringify, anda boleh mengawal peraturan penukaran dengan lebih terperinci. Berikut ialah contoh menggunakan tatasusunan untuk mengekalkan hanya ciri tertentu.
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,
passworddikecualikan supaya pencetakan log menjadi lebih selamat. Ini berguna apabila anda ingin membuang maklumat sensitif atas alasan keselamatan.
Menggunakan replacer sebagai fungsi (untuk penukaran dan penapisan nilai)
Jika anda memerlukan lebih fleksibiliti, anda boleh memberikan fungsi untuk memproses setiap kunci dan nilai. Berikut adalah contoh untuk mengekalkan Date sebagai rentetan 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 fungsi jenis
replacer, kunci dan nilai dihantar masuk dan nilai yang dikembalikan akan digunakan dalam JSON akhir.thismerujuk kepada objek induk, jadi ia juga boleh digunakan untuk penukaran bersarang.
Asas JSON.parse()
JSON.parse menukarkan rentetan JSON kembali kepada objek. Gunakan try/catch supaya anda boleh mengendalikan JSON yang tidak sah.
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 rentetan tidak sah, pengecualian akan dilemparkan, jadi pastikan sentiasa ada pengendalian pengecualian apabila berurusan dengan sumber luar.
Pemulihan khusus menggunakan reviver (contoh memulihkan Date)
Dengan menggunakan argumen kedua reviver untuk JSON.parse, anda boleh melakukan pemulihan nilai. Berikut adalah contoh menukar tarikh sebagai rentetan disimpan kembali kepada 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
reviverakan dipanggil untuk setiap kunci, dan nilai yang dikembalikan digunakan dalam objek akhir. Sila lakukan semakan format tarikh yang ketat mengikut keperluan aplikasi anda.
Cetakan elok dan argumen space
Untuk keluar dengan penjarakan bagi mudah dibaca, nyatakan nombor atau rentetan sebagai argumen ketiga dalam 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 bertujuan dibaca manusia, seperti log atau fail konfigurasi, adalah baik untuk menentukan penjarakan. Walau bagaimanapun, ambil perhatian bahawa ini akan meningkatkan saiz.
Cara mengendalikan rujukan bulat
JSON.stringify akan membaling TypeError jika terdapat rujukan bulat. Penyelesaian umum adalah dengan mencipta replacer menggunakan set seen untuk mengelak rujukan bulat.
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 boleh mengesan rujukan bulat dan mengelak kebocoran memori. Dalam kes rujukan bulat, ia akan memulangkan"[Circular]". Ia juga boleh menetapkan ID rujukan menggantikan"[Circular]".
Penyirihan khusus dengan kaedah toJSON
Jika anda tetapkan kaedah toJSON pada objek, JSON.stringify akan menggunakan nilai yang dikembalikan. Ini berguna jika anda ingin memasukkan peraturan penukaran untuk setiap jenis.
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"}
toJSONmembolehkan anda menentukan peraturan penyirihan di peringkat objek, menjadikannya lebih setempat dan intuitif daripada menggunakanreplacer.
Had dan peringatan untuk JSON
Contoh yang tidak boleh ditukar kepada JSON ialah undefined, fungsi, Symbol, BigInt, dan rujukan bulat. Ambil perhatian terhadap ketepatan nombor juga (seperti integer besar dan pembulatan titik apung 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}- Ketika mengendalikan
BigInt, tukarkan kepada rentetan atau tentukan representasinya denganreplaceratautoJSONkhusus.
Keselamatan (apabila mengendalikan JSON yang tidak dipercayai)
JSON.parse sendiri adalah selamat dan dianggap lebih selamat berbanding eval, namun adalah bahaya untuk terus mempercayai objek yang telah dinyahparsing dan menggunakannya secara langsung untuk akses ciri atau pertanyaan ke pangkalan data. Sentiasa sahkan dan pastikan data mematuhi skema yang dijangkakan.
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 pengesahan input (pengesahan skema), penggunaan pustaka seperti
ajvadalah kukuh.
Pertimbangan prestasi
Menyerih dan menyahserih objek besar secara kerap membebankan CPU dan memori. Jika perlu, anda boleh pertimbangkan menghantar hanya perbezaan, menggunakan format binari (seperti MessagePack), atau penstriman (memproses data secara bersiri). Dalam persekitaran pelayar, ada situasi di mana anda boleh menggunakan structuredClone (untuk penyalinan) atau objek boleh dipindah dalam postMessage.
Nasihat khusus (ringkas)
Anda juga boleh pertimbangkan perkara berikut:.
- Untuk log, elakkan cetakan elok dan gunakan JSON satu baris untuk kurangkan saiz.
- Objek yang sering disirih perlu diringkaskan terlebih dahulu, contohnya dengan membuang ciri yang tidak diperlukan.
- Gunakan
replaceruntuk minimumkan traversal dan keluarkan ciri tidak diperlukan.
Contoh praktikal: Aliran penghantaran/penerimaan permintaan API
Akhir sekali, berikut adalah urutan menunjukkan bagaimana untuk menukar objek kepada JSON dengan selamat untuk dihantar ke pelayan dan memulihkan tarikh daripada respons 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,
passworddikecualikan sebelum dihantar, dan tarikh dipulihkan menggunakanreviverselepas diterima. Dalam operasi sebenar, anda perlu menambah pengendalian ralat dan pemprosesan masa tamat.
Ringkasan
Dengan menggunakan JSON.stringify() dan JSON.parse(), anda boleh menukar antara objek dan rentetan. Anda boleh menyesuaikan proses penukaran menggunakan replacer dan reviver, dan jika anda laksanakan toJSON dalam kelas, anda boleh kawal setiap objek secara individu. Rujukan bulat, BigInt, fungsi, dan sebagainya tidak boleh dikendalikan secara langsung, jadi anda perlu memprosesnya terlebih dahulu.
Sentiasa sahkan input luaran, dan pastikan maklumat sensitif tidak termasuk dalam log atau komunikasi. Jika saiz data besar, lebih cekap untuk elakkan cetakan elok, pertimbangkan penghantaran perbezaan, atau guna format binari.
Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.