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 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:

javascript
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")); // 42

Son 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.

javascript
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'a çevrilemeyen değerler: undefined, fonksiyon, Symbol, NaN, Infinity

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:

javascript
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ğerNesne içindeDizi içindeTek başına
undefinedözellik atlanırnull olurundefined döner (metin değil)
fonksiyonözellik atlanırnull olurundefined döner
Symbolözellik atlanırnull olurundefined döner
NaN, Infinitynull olurnull olur"null"
DateISO metni (toJSON)ISO metniISO metni
Map, Set{} olur{} olur"{}"
BigIntTypeErrorTypeErrorTypeError
döngüsel referansTypeErrorTypeErrorTypeError

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.

javascript
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ı):

javascript
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:

javascript
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); // false

Reviver, 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.

javascript
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); // 12345678901234567890n

Sık yapılan hatalar

Sık yapılan hatalar: Zaten nesne olan değeri parse etmek, İki kez stringify etmek, Reviver içinde değer döndürmeyi unutmak, Map veya Set'i doğrudan göndermek
  • Zaten nesne olan değeri parse etmek: JSON.parse(obj) önce nesneyi metne çevirir ("[object Object]") ve SyntaxError verir. Değerin türünü kontrol edin.
  • İki kez stringify etmek: Zaten JSON metni olan bir değeri tekrar stringify etmek 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: parse yalnı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