JavaScript'te `JSON` sınıfı
Bu makale, JavaScript'teki JSON sınıfını açıklar.
JavaScript'teki JSON sınıfını pratik örneklerle açıklayacağız.
YouTube Video
JavaScript'te JSON sınıfı
JSON nesnesinin temel olarak iki yöntemi vardır. JSON.stringify() bir nesneyi JSON dizesine dönüştürür, JSON.parse() ise JSON dizesinden bir nesne oluşturur. JSON, yalnızca bazı JavaScript değerlerini ifade edebilen bir veri alışveriş formatıdır. Fonksiyonlar, undefined, Symbol ve döngüsel referanslar doğrudan JSON'a dönüştürülemez.
JSON.stringify()
İlk olarak, bir nesneyi JSON dizesine dönüştürmenin temel bir örneği.
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}
- Bu kod, sıradan bir nesnenin JSON dizesine çevrilmesinin en temel örneğidir.
JSON.stringifydizeyi eşzamanlı olarak döndürür.
JSON.stringify fonksiyonunun ikinci argümanı (replacer)
JSON.stringify'nin ikinci argümanı olan replacer ile dönüşüm kurallarını hassas şekilde kontrol edebilirsiniz. Yalnızca belirli özellikleri tutmak için dizinin kullanıldığı bir örnek.
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"}
- Bu örnekte, güvenli günlük çıktısı için
passwordhariç tutulmuştur. Güvenlik nedeniyle hassas bilgileri kaldırmak istediğinizde bu yararlıdır.
replacer'ı fonksiyon olarak kullanmak (değer dönüşümü ve filtreleme için)
Daha fazla esneklik isterseniz, her anahtarı ve değeri işlemek için bir fonksiyon verebilirsiniz. Aşağıda bir Date değerinin ISO dizesi olarak nasıl tutulacağına dair bir örnek var.
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"}
- Fonksiyon tipi
replacerkullanımında, anahtar ve değer aktarılır ve döndürülen değer son JSON'da kullanılır.thisüst nesneyi belirtir, bu yüzden iç içe dönüşümler için de kullanılabilir.
JSON.parse() temel bilgileri
JSON.parse bir JSON dizesini tekrar nesneye çevirir. Geçersiz JSON'u yönetebilmek için onu try/catch ile sarmalayın.
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}- Dize geçersizse bir istisna oluşur, bu nedenle harici kaynaklarla çalışırken her zaman istisna yönetimi uygulayın.
reviver kullanarak özel biçimde geri yükleme (Tarih nesnesi geri yükleme örneği)
JSON.parse fonksiyonunun ikinci argümanı olan reviver ile değer geri yüklemesi yapabilirsiniz. Saklanan bir dize tarihinin tekrar Date nesnesine çevrilmesinin bir örneği.
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
reviverher anahtar için çağrılır ve döndürülen değer son nesnede kullanılır. Lütfen uygulamanıza uygun şekilde sıkı tarih formatı kontrolü yapın.
Pretty-printing ve space argümanı
Okunabilirlik için girintiyle çıktı almak isterseniz, JSON.stringify fonksiyonuna üçüncü argüman olarak bir sayı veya dize aktarın.
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} */- Kayıt veya yapılandırma dosyası çıktısı gibi insan tarafından okunacak JSON'larda girinti belirtmek faydalıdır. Ancak, bunun boyutu artıracağını unutmayın.
Döngüsel referanslar nasıl yönetilir
Eğer döngüsel bir referans varsa, JSON.stringify bir TypeError fırlatır. Yaygın bir çözüm, döngüsel referanslardan kaçınmak için bir seen kümesi kullanarak replacer oluşturmaktır.
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]"}
WeakSetkullanarak, bellek sızıntısını önlerken döngüsel referansları tespit edebilirsiniz. Döngüsel bir referans durumunda,"[Circular]"döndürülür."[Circular]"yerine referans ID'si atamak da mümkündür.
toJSON yöntemi ile özel serileştirme
Eğer bir nesneye toJSON yöntemi tanımlarsanız, JSON.stringify bunun dönüş değerini kullanır. Bu, her tür için dönüştürme kurallarını gömmek istediğinizde faydalıdır.
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"}
toJSON, nesne düzeyinde serileştirme kuralları tanımlamanıza olanak verir vereplacerkullanmaktan daha yerel ve sezgisel olur.
JSON'un sınırlamaları ve dikkat edilmesi gerekenler
JSON'a çevrilemeyen başlıca örnekler: undefined, fonksiyonlar, Symbol, BigInt ve döngüsel referanslar. Sayısal hassasiyet konusunda da dikkatli olun (büyük tamsayılar ve IEEE kayan nokta yuvarlaması gibi).
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}BigIntile çalışırken, onu bir dizeye dönüştürün veya kendireplacerya datoJSONunuzu tanımlayarak gösterimini ayarlayın.
Güvenlik (güvenilmeyen JSON ile çalışırken)
JSON.parse'in kendisi güvenlidir ve eval'den daha güvenli kabul edilir, ancak ayrıştırılan nesneye güvenip onu doğrudan özellik erişimi veya veritabanı sorguları için kullanmak tehlikelidir. Her zaman verinin beklenen şemaya uygun olup olmadığını doğrulayın ve kontrol edin.
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}- Girdi doğrulama (şema doğrulama) için
ajvgibi kütüphaneler kullanmak sağlam bir yaklaşımdır.
Performans dikkate alınması gerekenler
Büyük nesnelerin sık sık serileştirilip tekrar seriden çıkarılması CPU ve belleğe yük bindirir. Gerekirse yalnızca farkları göndermeyi, ikili formatları (MessagePack gibi) veya akış yöntemini (veriyi sırayla işleme) düşünebilirsiniz. Tarayıcı ortamlarında, kopyalama için structuredClone veya postMessage ile taşınabilir nesneler kullanabileceğiniz durumlar vardır.
Spesifik tavsiyeler (kısa)
Aşağıdaki noktaları da göz önünde bulundurabilirsiniz:.
- Kayıtlar için pretty-print'ten kaçının ve boyutu azaltmak için tek satırlık JSON kullanın.
- Sık sık serileştirilen nesneler önceden hafifletilmeli, örneğin gereksiz özellikler kaldırılmalıdır.
- Gezintiyi en aza indirmek ve gereksiz özellikleri dışlamak için
replacerkullanın.
Pratik örnek: API isteği gönderme/alma akışı
Son olarak, bir nesneyi sunucuya gönderilmek üzere güvenli şekilde JSON'a çevirmenin ve alınan yanıttan tarih bilgisini geri yüklemenin akışını gösteren bir örnek.
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}- Bu örnekte,
passwordgönderilmeden önce hariç tutulur ve tarih bilgisi alındıktan sonrareviverile geri yüklenir. Gerçek uygulamada, hata yönetimi ve zaman aşımı işlemleri eklemeniz gerekir.
Özet
JSON.stringify() ve JSON.parse() ile nesneler ve dizeler arasında dönüşüm yapabilirsiniz. Dönüşüm sürecini replacer ve reviver ile özelleştirebilir, bir sınıfta toJSON uygularsanız her nesneyi ayrı ayrı kontrol edebilirsiniz. Döngüsel referanslar, BigInt, fonksiyonlar gibi şeyler doğrudan işlenemez, önceden işlem yapmanız gerekir.
Dış girdileri her zaman doğrulayın ve hassas bilgilerin kayıt ya da iletişimde yer almadığından emin olun. Veri boyutu büyükse, pretty-print'ten kaçınmak, fark iletişimini düşünmek veya ikili formatlar kullanmak daha verimlidir.
Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.