JSON.stringify() bir JavaScript değerini JSON metnine, JSON.parse() ise JSON metnini tekrar JavaScript değerine çevirir. API'ye veri göndermek, dosyaya ya da önbelleğe kaydetmek ve gelen yanıtı okumak için bu iki fonksiyon kullanılır. stringify isteğe bağlı bir replacer ve space argümanı, parse ise bir reviver argümanı alır. Her JavaScript değeri JSON'a çevrilemez: undefined, fonksiyonlar ve Symbol atlanır, BigInt ise hata fırlatır.
Bu yazıda iki fonksiyonun bütün argümanlarını, toJSON() metodunu, JSON'a çevrilemeyen değerleri ve sık yapılan hataları Node.js 24 ile denenmiş örneklerle anlatıyoruz. JSON ile tablo verisi arasındaki dönüşüm için CSV ve JSON dönüşümü yazısına, arama motorlarına yönelik yapılandırılmış veri için Schema.org JSON-LD rehberine bakabilirsiniz. Genel yol haritası JavaScript öğrenme rehberinde.
JSON, JavaScript nesnesi değildir

JSON, JavaScript sözdizimine dayanan ama ondan ayrı bir veri biçimidir. MDN'ye göre başlıca farklar şunlardır: özellik adları çift tırnaklı metin olmalıdır, sondaki fazladan virgül (trailing comma) yasaktır, metinler yalnızca çift tırnakla yazılır, sayılarda baştaki sıfır yasaktır, NaN, Infinity, undefined ve yorum satırları desteklenmez. JSON yalnızca nesne, dizi, sayı, metin, boolean ve null değerlerini taşıyabilir.
JSON.parse: metni değere çevirmek
JSON.parse(text) geçerli bir JSON metnini nesne, dizi, metin, sayı, boolean ya da null olarak döndürür. Metin JSON kurallarına uymuyorsa SyntaxError fırlatır. Dışarıdan gelen veriyi her zaman try...catch içinde ayrıştırın:
const metin = '{"id": 7, "ad": "Deniz", "etiketler": ["js", "node"], "aktif": true}';
const kullanici = JSON.parse(metin);
console.log(kullanici.etiketler[1]); // node
function guvenliParse(s) {
try {
return JSON.parse(s);
} catch (e) {
console.log(e.name);
return null;
}
}
guvenliParse("{'ad': 1}"); // SyntaxError (tek tırnak)
guvenliParse('{"ad": 1,}'); // SyntaxError (sondaki virgül)
console.log(guvenliParse("42")); // 42Son satırın gösterdiği gibi JSON metninin kökü bir nesne olmak zorunda değildir; "42", "true" veya "null" de geçerli JSON metinleridir.
JSON.stringify: değeri metne çevirmek
JSON.stringify(value, replacer, space) değeri JSON metnine çevirir. Nesnenin yalnızca kendi ve numaralandırılabilir özellikleri yazılır; sıra Object.keys() ile aynıdır. space argümanı çıktıyı okunur hale getirir: sayı verirseniz her seviye o kadar boşlukla girintilenir (en fazla 10), metin verirseniz o metin (ilk 10 karakteri) girinti olarak kullanılır.
const urun = { ad: "Kalem", fiyat: 15, renkler: ["mavi", "siyah"] };
console.log(JSON.stringify(urun));
// {"ad":"Kalem","fiyat":15,"renkler":["mavi","siyah"]}
console.log(JSON.stringify(urun, null, 2));
/*
{
"ad": "Kalem",
"fiyat": 15,
"renkler": [
"mavi",
"siyah"
]
}
*/space metin olarak da verilebilir. Örneğin JSON.stringify({ a: 1 }, null, "--") her girinti seviyesinin başına iki tire koyar. Girinti çıktıyı büyüttüğü için ağ üzerinden gönderilecek veride genellikle kullanılmaz; log ve yapılandırma dosyası gibi insanların okuyacağı yerlerde işe yarar. replacer kullanmadan space vermek istediğinizde ikinci argümana null yazın.
JSON'a çevrilemeyen değerler

JSON'un desteklemediği değerlerle karşılaşınca stringify sessizce bir şeyler kaybedebilir ya da hata fırlatabilir. Davranış, değerin nerede durduğuna göre değişir:
const veri = {
a: undefined,
b: () => 1,
c: Symbol("x"),
d: NaN,
e: Infinity,
f: new Date(Date.UTC(2026, 10, 5)),
g: new Map([["k", 1]]),
h: new Set([1, 2]),
dizi: [undefined, () => 1, NaN],
};
console.log(JSON.stringify(veri));
// {"d":null,"e":null,"f":"2026-11-05T00:00:00.000Z","g":{},"h":{},"dizi":[null,null,null]}
console.log(JSON.stringify(undefined)); // undefined
try {
JSON.stringify({ sayi: 10n });
} catch (e) {
console.log(e.name + ": " + e.message);
}
// TypeError: Do not know how to serialize a BigInt
const dongu = { ad: "x" };
dongu.kendisi = dongu;
try {
JSON.stringify(dongu);
} catch (e) {
console.log(e.name); // TypeError
}| Değer | Nesne içinde | Dizi içinde | Tek başına |
|---|---|---|---|
| undefined | özellik atlanır | null olur | undefined döner (metin değil) |
| fonksiyon | özellik atlanır | null olur | undefined döner |
| Symbol | özellik atlanır | null olur | undefined döner |
| NaN, Infinity | null olur | null olur | "null" |
| Date | ISO metni (toJSON) | ISO metni | ISO metni |
| Map, Set | {} olur | {} olur | "{}" |
| BigInt | TypeError | TypeError | TypeError |
| döngüsel referans | TypeError | TypeError | TypeError |
replacer: neyin yazılacağını seçmek
replacer bir dizi ise yalnızca o adlara sahip özellikler yazılır. Bir fonksiyon ise her anahtar-değer çifti için çağrılır; döndürdüğünüz değer yazılır, undefined döndürürseniz özellik çıktıdan atlanır. Fonksiyon ilk olarak kökün kendisi için, boş metin anahtarıyla çağrılır.
const kayit = { id: 1, ad: "Ece", sifre: "gizli", olusturma: 1730764800000 };
// Dizi: yalnızca bu alanlar
console.log(JSON.stringify(kayit, ["id", "ad"])); // {"id":1,"ad":"Ece"}
// Fonksiyon: hassas alanı at
console.log(JSON.stringify(kayit, (k, v) => (k === "sifre" ? undefined : v)));
// {"id":1,"ad":"Ece","olusturma":1730764800000}
// Map ve BigInt'i elle dönüştürmek
const durum = { sayac: 12n, ayar: new Map([["tema", "koyu"]]) };
const metin = JSON.stringify(durum, (k, v) => {
if (typeof v === "bigint") return v.toString();
if (v instanceof Map) return Object.fromEntries(v);
return v;
});
console.log(metin); // {"sayac":"12","ayar":{"tema":"koyu"}}toJSON: nesnenin kendi JSON biçimi
Bir nesnenin toJSON() metodu varsa stringify nesnenin kendisi yerine bu metodun döndürdüğü değeri yazar. Date nesneleri bu yüzden ISO biçimli metne dönüşür. Kendi sınıflarınızda dışarıya hangi alanların çıkacağını bu yolla belirleyebilirsiniz (sınıflar için class yazısı):
class Hesap {
#token = "gizli";
constructor(ad, bakiye) {
this.ad = ad;
this.bakiye = bakiye;
}
toJSON() {
return { ad: this.ad, bakiye: this.bakiye.toFixed(2) };
}
}
console.log(JSON.stringify({ hesap: new Hesap("Ana", 1500) }));
// {"hesap":{"ad":"Ana","bakiye":"1500.00"}}
console.log(JSON.stringify(new Date(Date.UTC(2026, 0, 1))));
// "2026-01-01T00:00:00.000Z"reviver: ayrıştırırken dönüştürmek
JSON.parse(text, reviver) çağrısında reviver fonksiyonu, ayrıştırılan her değer için en içteki değerlerden başlayıp köke doğru çağrılır. Döndürdüğünüz değer o özelliğin yeni değeri olur; undefined döndürürseniz özellik silinir. Bu yüzden dönüştürmediğiniz değerleri olduğu gibi geri döndürmeyi unutmayın. En yaygın kullanım, metin olarak gelen tarihleri tekrar Date nesnesine çevirmektir:
const gelen = '{"no": 5, "tarih": "2026-11-05T10:30:00.000Z", "not": null}';
const siparis = JSON.parse(gelen, (anahtar, deger) => {
if (anahtar === "tarih") return new Date(deger);
if (deger === null) return undefined; // null alanları sil
return deger;
});
console.log(siparis.tarih instanceof Date); // true
console.log(siparis.tarih.getUTCHours()); // 10
console.log("not" in siparis); // falseReviver, değer ayrıştırıldıktan sonra çalışır. Bu yüzden JSON metnindeki çok büyük bir sayı, reviver çağrılmadan önce JavaScript sayısına çevrilir ve hassasiyet kaybedebilir. MDN, reviver fonksiyonuna üçüncü argüman olarak bir context nesnesi geçirildiğini ve ilkel değerlerde context.source alanının değerin ham JSON metnini taşıdığını belgeler. Bu özellik yenidir; Node.js 24 üzerinde çalıştı, diğer ortamlar için MDN uyumluluk tablosuna bakın.
const buyuk = '{"id": 12345678901234567890}';
console.log(JSON.parse(buyuk).id); // 12345678901234567000
const dogru = JSON.parse(buyuk, (k, v, context) =>
k === "id" ? BigInt(context.source) : v,
);
console.log(dogru.id); // 12345678901234567890nSık yapılan hatalar

- Zaten nesne olan değeri parse etmek:
JSON.parse(obj)önce nesneyi metne çevirir ("[object Object]") veSyntaxErrorverir. Değerin türünü kontrol edin. - İki kez stringify etmek: Zaten JSON metni olan bir değeri tekrar
stringifyetmek tırnakları kaçışlı bir metin üretir; karşı taraf bir nesne yerine metin alır. - Reviver içinde değer döndürmeyi unutmak: Fonksiyon bir şey döndürmezse bütün özellikler silinir.
- Map veya Set'i doğrudan göndermek: Çıktıda
{}görürsünüz; replacer ya da Object.fromEntries() ile dönüştürün. - JSON çıktısına güvenip doğrulama yapmamak:
parseyalnızca sözdizimini denetler, alanların varlığını veya türünü değil. API yanıtlarında beklediğiniz yapıyı ayrıca kontrol edin.
Sık Sorulan Sorular
JSON.stringify anahtar sırasını korur mu?
MDN'ye göre özellikler Object.keys() ile aynı, iyi tanımlı bir sırada gezilir; aynı nesne her seferinde aynı metni üretir ve JSON.parse(JSON.stringify(obj)) aynı anahtar sırasına sahip bir nesne verir (nesne tamamen JSON'a çevrilebiliyorsa).
"Unexpected token" ya da "is not valid JSON" hatası neden çıkar?
JSON.parse() verilen metin JSON kurallarına uymadığında SyntaxError fırlatır; mesajın tam metni motora göre değişir. Sık nedenler: tek tırnak, sondaki virgül, yorum satırı, boş metin ya da JSON yerine gelen bir HTML hata sayfası. Ayrıştırmadan önce metnin ilk birkaç karakterini loglamak sorunu çoğu zaman hemen gösterir. Genel hata mesajları listesi için sık JavaScript hata mesajları yazısına bakabilirsiniz.
Node.js'te JSON dosyası nasıl okunur?
Dosyayı metin olarak okuyup JSON.parse() ile ayrıştırmak en taşınabilir yoldur. Express gibi çatılarla JSON gövdesi alan bir API yazıyorsanız Node.js REST API geliştirme yazısına bakabilirsiniz.
JSON ile CSV arasında nasıl dönüşüm yapılır?
Düz bir nesne dizisini satırlara, anahtarları sütun başlıklarına eşleyerek dönüştürebilirsiniz; tırnak ve virgül kuralları için RFC 4180 ayrıntılarını içeren CSV-JSON dönüşüm yazısına bakın.
JSON ile JSON-LD aynı şey mi?
JSON-LD, JSON sözdizimini kullanan ve bağlantılı veri anlamı ekleyen bir biçimdir. Bir JSON-LD bloğu da JSON.stringify() ile üretilebilir; Schema.org kullanımı için JSON-LD rehberine bakın.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: JavaScript öğrenme rehberi · CSV ve JSON dönüşümü · Schema.org JSON-LD · Map, Set ve WeakMap · Hata yönetimi ve try...catch