At parse JSON i JavaScript er noget, du vil gøre hundredvis af gange som webudvikler. Heldigvis har JavaScript indbygget understøttelse til det — ingen biblioteker nødvendige. Men der er mere nuance i JSON.parse() og JSON.stringify() end dokumentationen afslører. Lad os gennemgå det ordentligt.

JSON.parse() — gøre en streng til et objekt

JSON.parse() tager en JSON-formateret streng og konverterer den til en JavaScript-værdi. Den værdi er typisk et objekt eller et array, men det kan også være en streng, et tal, en boolean eller null:

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"

Bemærk, at inputtet skal være en streng. En hyppig fejl er at forsøge at parse en værdi, der allerede er et objekt — JSON.parse({}) kaster en SyntaxError, fordi det konverterer objektet til "[object Object]" først, hvilket ikke er gyldig JSON.

Omslut altid JSON.parse() i en try/catch

Det her er noget, ingen fortæller dig: JSON.parse() kaster en SyntaxError, hvis inputtet er ugyldig JSON. Hvis du parser data fra et API, brugerinput eller en fil, bør du altid håndtere den fejl. Et enkelt fejlformateret svar kan crashe din app, hvis du ikke gør det:

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"

Jeg bruger en wrapper som den her i næsten hvert projekt. Det gør fejlhåndteringen konsistent og forhindrer grimme uopfangede undtagelser i at boble op til dit UI.

JSON.stringify() — gøre et objekt til en streng

JSON.stringify() gør det omvendte: den konverterer en JavaScript-værdi til en JSON-streng. Du bruger dette, når du sender data til et API, gemmer til localStorage eller skriver til en fil:

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"
// }

Det tredje argument til JSON.stringify() er indrykningsniveauet. Brug af 2 eller 4 giver dig læsbart output. Standardindstillingen (intet tredje argument) giver dig kompakt, minificeret JSON — bedre til netværkstransmission.

Hvad stringify() stille udelader

Dette bider regelmæssigt udviklere. JSON.stringify() udelader stille visse værdier, fordi JSON ikke understøtter dem:

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
Pas på: Hvis du stringifierer et objekt med undefined-værdier og derefter parser det, vil de nøgler mangle fuldstændigt. Det kan forårsage subtile fejl, hvis din kode tjekker obj.key === undefined senere.

Hente JSON fra et API — det virkelige mønster

I praksis sker de fleste JSON-parsninger, når du henter data fra et API. Fetch API gør det ligetil — response.json() håndterer parsningen for dig:

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() er i bund og grund JSON.parse(await response.text()). Det kaster også, hvis svarteksten ikke er gyldig JSON, så det er værd at fange det separat i produktionskode.

Arbejde med indlejrede JSON-data

Dybt indlejret JSON er almindeligt i rigtige API'er. Sådan navigerer du det sikkert uden at crashe på manglende nøgler:

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 (?.) og nullish coalescing (??) er moderne JavaScript-funktioner — begge del af ECMAScript-specifikationen siden 2020 — som gør det meget sikrere at arbejde med usikre JSON-strukturer. Brug dem frit — de understøttes i alle moderne browsere og Node.js 14+.

Funktionerne replacer og reviver

Både JSON.stringify() og JSON.parse() accepterer et andet argument, der lader dig tilpasse transformationen. De er genuint nyttige til virkelige scenarier:

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-mønstret er særligt nyttigt til at gendanne Date-objekter efter en tur-retur gennem JSON, da JSON ikke har en native datotype.

Nyttige værktøjer

Når du arbejder med JSON i JavaScript-projekter, sparer disse værktøjer tid: JSON Formatter til at pretty-printe minificerede API-svar, JSON Validator til at kontrollere syntaksfejl, JSON Path til at forespørge specifikke felter fra store payloads, og JSON Escape når du skal indlejre JSON i en streng. For mere dybde er MDN JSON-referencen fremragende.

Afslutning

JSON.parse() og JSON.stringify() er de to funktioner, du har brug for. De vigtigste vaner at opbygge: omslut altid parse() i try/catch, brug optional chaining til nEstlet adgang, og vid, hvad stringify() stille udelader. Få de tre på plads, og du klarer 99% af virkelige JSON-scenarier uden overraskelser.