JavaScript'te JSON parse etmek, bir web geliştiricisi olarak yüzlerce kez yapacağın bir şey. Neyse ki JavaScript'in buna yerleşik desteği var — kütüphane gerekmez. Ama JSON.parse() ve JSON.stringify() içinde dökümantasyonun ima ettiğinden daha fazla nüans var. Hepsini düzgünce ele alalım.

JSON.parse() — Bir String'i Object'e Dönüştürmek

JSON.parse(), JSON formatındaki bir string'i alır ve JavaScript değerine dönüştürür. Bu değer genellikle bir object veya array olur, ama string, number, boolean veya null da olabilir:

js
const jsonString = '{"name": "Alice", "age": 30, "active": true}';
const user = JSON.parse(jsonString);

console.log(user.name);    // "Alice"
console.log(user.age);     // 30
console.log(user.active);  // true
console.log(typeof user);  // "object"

Girişin bir string olması gerektiğine dikkat et. Yaygın bir hata, zaten bir object olan bir değeri parse etmeye çalışmaktır — JSON.parse({}), object'i önce "[object Object]"'e dönüştürdüğü için SyntaxError fırlatır, ki bu geçerli JSON değildir.

JSON.parse()'ı Her Zaman try/catch ile Sar

Kimsenin sana söylemediği şey şu: JSON.parse(), girdi geçersiz JSON ise SyntaxError fırlatır. Bir API'den, kullanıcı girdisinden veya bir dosyadan veri parse ediyorsan, bu hatayı her zaman ele almalısın. Tek bir bozuk yanıt, bunu yapmazsan uygulamanı çökertebilir:

js
function safeParseJSON(str) {
  try {
    return { data: JSON.parse(str), error: null };
  } catch (err) {
    return { data: null, error: err.message };
  }
}

const { data, error } = safeParseJSON('{"name": "Alice"}');
if (error) {
  console.error('Invalid JSON:', error);
} else {
  console.log(data.name); // "Alice"
}

// Handles bad input gracefully
const result = safeParseJSON('not json at all');
console.log(result.error); // "Unexpected token 'o', "not json "... is not valid JSON"

Bu tür bir wrapper'ı neredeyse her projede kullanıyorum. Hata yönetimini tutarlı hale getirir ve çirkin yakalanmamış exception'ların UI'ına kadar kabarmesini önler.

JSON.stringify() — Bir Object'i String'e Dönüştürmek

JSON.stringify() tersini yapar: bir JavaScript değerini JSON string'e dönüştürür. Bunu bir API'ye veri gönderirken, localStorage'a kaydederken veya dosyaya yazarken kullanırsın:

js
const user = {
  name: "Bob",
  age: 25,
  roles: ["admin", "editor"],
  password: "secret123" // we'll handle this later
};

// Basic usage
const jsonString = JSON.stringify(user);
// '{"name":"Bob","age":25,"roles":["admin","editor"],"password":"secret123"}'

// Pretty-printed (great for logs and file output)
const prettyJson = JSON.stringify(user, null, 2);
console.log(prettyJson);
// {
//   "name": "Bob",
//   "age": 25,
//   "roles": ["admin", "editor"],
//   "password": "secret123"
// }

JSON.stringify()'ın üçüncü argümanı girinti seviyesidir. 2 veya 4 kullanmak okunabilir çıktı verir. Varsayılan (üçüncü argüman yok) sıkıştırılmış, minify edilmiş JSON verir — ağ aktarımı için daha iyi.

stringify()'ın Sessizce Düşürdükleri

Bu, geliştiricileri düzenli olarak ısırır. JSON.stringify(), JSON tarafından desteklenmediği için belirli değerleri sessizce atlar:

js
const data = {
  name: "Alice",
  greet: function() { return "hi"; },   // Functions → dropped
  undef: undefined,                      // undefined → dropped
  sym: Symbol("key"),                    // Symbols → dropped
  nan: NaN,                              // NaN → null
  inf: Infinity,                         // Infinity → null
  date: new Date("2024-01-15")           // Dates → ISO string
};

console.log(JSON.stringify(data, null, 2));
// {
//   "name": "Alice",
//   "nan": null,
//   "inf": null,
//   "date": "2024-01-15T00:00:00.000Z"
// }
// greet, undef, sym are GONE
Dikkat: undefined değerlerine sahip bir object'i stringify edip sonra parse edersen, o key'ler tamamen kaybolur. Kodun daha sonra obj.key === undefined kontrolü yapıyorsa, bu ince hatalara yol açabilir.

Bir API'den JSON Almak — Gerçek Dünya Kalıbı

Pratikte JSON parse etmenin büyük çoğunluğu, bir API'den veri çekerken gerçekleşir. Fetch API bunu basit hale getirir — response.json() parse işlemini senin için halleder:

js
async function getUser(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);

    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }

    const user = await response.json(); // parses JSON automatically
    return user;
  } catch (err) {
    console.error('Failed to fetch user:', err);
    return null;
  }
}

const user = await getUser(42);
if (user) {
  console.log(`Hello, ${user.name}!`);
}

response.json() özünde JSON.parse(await response.text())'tır. Yanıt gövdesi geçerli JSON değilse de hata fırlatır, bu yüzden üretim kodunda bunu ayrıca yakalamak mantıklıdır.

İç İçe JSON Verisiyle Çalışmak

Gerçek API'lerde derin iç içe JSON yaygındır. İşte eksik key'lerde crash yaşamadan güvenli bir şekilde nasıl gezineceğin:

js
const apiResponse = {
  "user": {
    "profile": {
      "address": {
        "city": "Berlin"
      }
    }
  }
};

// Unsafe — throws if any level is undefined
const city1 = apiResponse.user.profile.address.city; // "Berlin"

// Safe with optional chaining (ES2020+) — returns undefined instead of throwing
const city2 = apiResponse?.user?.profile?.address?.city; // "Berlin"
const zip   = apiResponse?.user?.profile?.address?.zip;  // undefined (not a crash)

// With a fallback using nullish coalescing
const country = apiResponse?.user?.profile?.address?.country ?? "Unknown";

Optional chaining (?.) ve nullish coalescing (??) modern JavaScript özellikleri — ikisi de 2020'den beri ECMAScript spec'inin parçası — ve belirsiz JSON yapılarıyla çalışmayı çok daha güvenli hale getiriyor. Gönül rahatlığıyla kullan — tüm modern tarayıcılarda ve Node.js 14+'ta destekleniyor.

replacer ve reviver Fonksiyonları

Hem JSON.stringify() hem de JSON.parse(), dönüşümü özelleştirmene izin veren bir ikinci argüman kabul eder. Bunlar gerçek dünya senaryolarında işe yarıyor:

js
// replacer: filter or transform values during stringify
const user = { name: "Alice", password: "s3cr3t", age: 30 };
const safe = JSON.stringify(user, ["name", "age"]); // only include these keys
// '{"name":"Alice","age":30}'  — password is excluded

// reviver: transform values during parse
const dateJson = '{"name": "Alice", "createdAt": "2024-01-15T09:30:00Z"}';
const parsed = JSON.parse(dateJson, (key, value) => {
  if (key === "createdAt") return new Date(value); // convert string to Date
  return value;
});
console.log(parsed.createdAt instanceof Date); // true
console.log(parsed.createdAt.getFullYear());   // 2024

Reviver kalıbı, JSON'un native bir tarih tipi olmadığı için JSON üzerinden bir tur attıktan sonra Date object'lerini geri yüklemek için özellikle kullanışlıdır.

Faydalı Araçlar

JavaScript projelerinde JSON ile çalışırken bu araçlar zaman kazandırır: minify edilmiş API yanıtlarını güzel yazdırmak için JSON Formatter, sözdizimi hatalarını kontrol etmek için JSON Validator, büyük payload'lardan belirli alanları sorgulamak için JSON Path ve bir string içine JSON gömmek gerektiğinde JSON Escape. Daha fazla derinlik için MDN JSON referansı mükemmeldir.

Özet

İhtiyacın olan iki fonksiyon JSON.parse() ve JSON.stringify(). Edinmen gereken temel alışkanlıklar: parse()'ı her zaman try/catch içine sar, iç içe erişim için optional chaining kullan ve stringify()'ın sessizce neler düşürdüğünü bil. Bu üçünü doğru yaptığında gerçek dünyadaki JSON senaryolarının %99'unu sürpriz yaşamadan halledersin.