Perbandingan Pustaka Penghuraian dan Pemprosesan JSON
Inti pati: API asli paling pantas, penghurai toleran memberikan offset. Pilih berdasarkan tiga perkara: lokasi ralat, sama ada teks asal dikekalkan, dan sama ada sempadan jelas.

Kesimpulan utama: klasifikasikan keperluan dahulu, kemudian bandingkan pelaksanaan — gunakan JSON.parse asli untuk nilai baca sahaja, jsonc-parser apabila anda memerlukan offset atau mesti mengekalkan pemformatan asal, dan tambah pustaka pertanyaan atau tampalan hanya di tempat yang diperlukan; muatkan pustaka besar secara lazy mengikut halaman dan buang yang tidak diselenggara.
Setiap pustaka mendakwa "pantas, kecil dan lengkap". Yang benar-benar membezakan mereka ialah berapa banyak maklumat yang boleh mereka berikan apabila sesuatu berlaku salah.
1. Empat kategori mengikut tujuan
| Kategori | Pustaka wakil | Apa yang diselesaikan |
|---|---|---|
| Penghuraian standard | JSON.parse / JSON.stringify |
Sintaks ↔ objek, kelajuan dahulu |
| Penghuraian toleran + penyuntingan | jsonc-parser, json5 |
Input dengan komen, ralat tepat hingga offset, pengubahsuaian yang mengekalkan pemformatan |
| Pertanyaan | jsonpath-plus, jsonpath |
Pilih nod mengikut ungkapan |
| Mutasi | fast-json-patch, immer |
Jana/gunakan tampalan, kemas kini tidak boleh ubah |
Kenal pasti kategori anda dahulu, kemudian bandingkan pelaksanaan konkrit — jika tidak, mudah untuk menggunakan pustaka pertanyaan untuk melakukan kerja penghurai.
2. Perbandingan sebelah-menyebelah
| Pustaka | Lokasi ralat | Toleransi (komen/koma di hujung) | Mengekalkan pemformatan asal | Senario sesuai |
|---|---|---|---|---|
JSON.parse |
Mesej dan kedudukan sahaja (bergantung pada enjin) | ✗ | ✗ | Penghuraian lalai, data API |
jsonc-parser |
offset tepat + kod ralat |
✓ | ✓ (modify + applyEdits) |
Editor, fail konfigurasi |
json5 |
Maklumat baris dan lajur | ✓ (lebih longgar) | ✗ | Membaca konfigurasi JSON5 |
jsonlint |
Maklumat baris dan lajur | ✗ | ✗ | Rujukan sahaja, tidak diselenggara secara aktif |
jsonpath-plus |
Ralat sintaks ungkapan | — | — | Pertanyaan mengikut ungkapan |
fast-json-patch |
Ralat peringkat operasi | — | — | Penjanaan dan penggunaan tampalan |
lz-string |
— | — | — | Memampatkan JSON ke dalam URL |
Mesej ralat JSON.parse berbeza-beza merentas enjin. V8 menghasilkan sesuatu seperti
Unexpected token } in JSON at position 42, tetapi sama ada kedudukan itu tepat bergantung pada versi enjin;
jsonc-parser sebaliknya mengembalikan { error, offset, length } berstruktur yang stabil, yang sesuai untuk penanda editor.
3. Empat titik keputusan utama
3.1 Adakah anda memerlukan offset
Jika anda membina editor dan mahukan "klik ralat untuk melompat ke baris berkaitan", anda mesti mempunyai offset. Ujiannya mudah: jika mesej ralat anda hanya boleh mencetak "JSON tidak sah", pengguna terpaksa memburunya sendiri.
import { parse, printParseErrorCode } from 'jsonc-parser';
const errors: Array<{ error: number; offset: number; length: number }> = [];
parse(text, errors, { allowTrailingComma: true, disallowComments: false });
if (errors.length > 0) {
const firstError = errors[0];
console.error(`${printParseErrorCode(firstError.error)} at offset ${firstError.offset}`);
}
3.2 Adakah anda perlu mengekalkan teks asal
Hanya membaca nilai → mana-mana penghurai sesuai. "Ubah satu medan dan kekalkan semua yang lain tepat seperti asal" → anda mesti menggunakan API gaya penyuntingan, bukan "huraikan → ubah objek → siri semula".
Yang terakhir menghilangkan: komen, susunan kunci (dalam sesetengah pelaksanaan), gaya indentasi, notasi literal nombor (1e3 menjadi 1000), dan bentuk escape (\u4e2d menjadi aksara sebenar).
3.3 Adakah tingkah laku sempadan jelas
Sebelum memilih pustaka, semak dokumentasi untuk tiga perkara:
- Bagaimana kunci pendua dikendalikan (kekalkan yang terakhir / naikkan ralat);
- Sama ada integer besar kehilangan ketepatan (kebanyakan pustaka JS kehilangan, kerana semuanya melalui
Number); - Skop sokongan untuk BOM, komen dan koma di hujung.
Jika tiada dokumentasi, tulis sampel kecil dan uji sendiri. Itu lebih boleh dipercayai daripada membaca README.
3.4 Status penyelenggaraan
Risiko pustaka JSON bukanlah ciri yang hilang, tetapi pengabaian jangka panjang: tiada sesiapa akan menghantar tampalan keselamatan lagi (pencemaran prototaip, ReDoS).
4. Perbandingan dengan bahasa lain
| Bahasa | Pustaka standard / pustaka arus perdana | Perbezaan utama |
|---|---|---|
| JavaScript | JSON.parse |
Semua nombor ialah ketepatan berganda |
| TypeScript | Sama seperti di atas + jsonc-parser / zod |
Jenis wujud hanya pada masa kompilasi |
| Go | encoding/json |
float64 secara lalai, gunakan UseNumber() untuk mengekalkan ketepatan; json.RawMessage untuk penghuraian tertangguh |
| Java | Jackson / Gson / Moshi | Dengan Jackson, berhati-hati dengan risiko mengaktifkan penjenisan lalai |
| Python | json / orjson |
parse_float=Decimal mengekalkan ketepatan; orjson lebih pantas tetapi tidak menyokong semua jenis |
| Rust | serde_json |
Penyahsirian kuat jenis; ciri arbitrary_precision mengekalkan ketepatan |
| C++ | simdjson / RapidJSON | simdjson menyasarkan kadar pemprosesan penghuraian, RapidJSON lebih serba guna |
Apabila bertukar data merentas bahasa, perkara paling mudah tersandung masih ketepatan nombor dan format masa; pemilihan pustaka hanya boleh mengurangkan, bukan menghapuskannya.
5. Gabungan tipikal
Pilihan 1: Laman alat (bahagian pelayar)
Parsing and error location: jsonc-parser
Editor: CodeMirror 6 + @codemirror/lang-json
Query: jsonpath-plus
Patch: fast-json-patch
Share links: lz-string
Ciri penentu gabungan ini ialah semuanya berjalan secara setempat dan tiada data dimuat naik, yang sepadan dengan jangkaan privasi laman utiliti.
Pilihan 2: Gerbang API bahagian pelayan
Validation: Ajv (compile the schema once, reuse it)
Parsing: native JSON.parse (together with a body size limit)
Deferred parsing of large fields: keep the raw string, parse only when needed
Jangan perkenalkan pustaka pertanyaan/tampalan ke dalam lapisan gerbang untuk melaksanakan logik perniagaan — itu kerja lapisan perniagaan.
Pilihan 3: CLI dan skrip
Pick fields: jq
Format conversion: yq / dasel
Interactive browsing: jless
Batch validation: ajv-cli
6. Kesan sebenar saiz bundel dan prestasi
jsonc-parsersangat kecil dan sesuai untuk bundel utama;json5lebih besar sedikit daripadajsonc-parserkerana ia menyokong lebih banyak sintaks;jsonpath-plusmerangkumi penilaian ungkapan dan jauh lebih besar, jadi ia patut dimuatkan secara lazy mengikut halaman;fast-json-patchbersaiz sederhana dan hanya diperlukan apabila anda mempunyai ciri perbandingan.
Pengoptimuman adalah mudah: import secara dinamik mengikut halaman, dan jangan letakkan mereka dalam ketulan skrin pertama.
const { JSONPath } = await import('jsonpath-plus');
7. Senarai semak
- [ ] Pilih pustaka mengikut tujuan; jangan gunakan pustaka pertanyaan untuk penghuraian;
- [ ] Gunakan
jsonc-parserapabila anda memerlukan lokasi ralat yang tepat; - [ ] Gunakan API gaya penyuntingan apabila komen dan pemformatan mesti dikekalkan;
- [ ] Uji tiga tingkah laku sempadan dalam amalan: kunci pendua, integer besar dan BOM;
- [ ] Perhatikan status penyelenggaraan pustaka dan nasihat keselamatan;
- [ ] Import pustaka besar secara dinamik mengikut keperluan.
Soalan Lazim
Bagaimana saya memilih pustaka JSON untuk saiz projek saya?
Alat kecil yang hanya membaca data API boleh kekal dengan JSON.parse asli. Projek yang memerlukan lokasi ralat bertaraf editor atau mesti mengekalkan pemformatan asal patut menggunakan jsonc-parser. Gerbang bahagian pelayan hanya memerlukan pengesahan dan penghuraian, menyerahkan pustaka pertanyaan dan tampalan kepada lapisan perniagaan, manakala skrip CLI boleh menggunakan jq, yq dan ajv-cli secara terus.
Mengapa status penyelenggaraan lebih penting daripada bilangan ciri?
Risiko sebenar pustaka JSON ialah pengabaian jangka panjang, bukan ciri yang hilang: tiada sesiapa akan menghantar tampalan keselamatan untuk pencemaran prototaip atau ReDoS. Walau selengkap mana pun senarai ciri, pustaka yang terhenti akan meninggalkan anda menampal sendiri. Anggap penyelenggaraan dan nasihat keselamatan sebagai kriteria keras dan bukannya membandingkan jadual ciri.
Patutkah saya menggunakan JSON.parse untuk mengubah satu medan dan mengekalkan komen serta indentasi?
Tidak. Menghuraikan, mengubah objek, kemudian menyiri semula akan menghilangkan komen, susunan kunci, gaya indentasi, notasi literal nombor (1e3 menjadi 1000), dan bentuk escape (\u4e2d menjadi aksara sebenar). Mengubah satu medan sambil mengekalkan semua yang lain memerlukan API gaya penyuntingan seperti modify dan applyEdits dalam jsonc-parser.