Sobes.tech
Middle+

Hoe objecten uit JSON herstellen zodat de metadata behouden blijven?

sobes.tech AI

Antwoord van AI

Om objecten met opgeslagen metadata uit JSON te herstellen, kun je JSON.parse() gebruiken in combinatie met een reviver-functie. Reviver is een optionele functie die wordt aangeroepen voor elk sleutel-waarde paar tijdens het parseren van JSON. Het stelt je in staat om gedecodeerde waarden te wijzigen voordat ze worden teruggegeven.

Voorbeeld van het gebruik van reviver om het type te behouden:

const jsonString = '{"date": "2023-10-27T10:00:00.000Z", "regexp": "/test/i"}';

const restoredObject = JSON.parse(jsonString, (key, value) => {
  if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
    return new Date(value);
  }
  if (typeof value === 'string' && /^\/.+\/[gimyus]*$/.test(value)) {
    try {
       const match = value.match(/^\/(.+)\/([gimyus]*)$/);
       if (match) {
           return new RegExp(match[1], match[2]);
       }
    } catch (e) {
    }
  }
  return value;
});

console.log(restoredObject.date instanceof Date); // true
console.log(restoredObject.regexp instanceof RegExp); // true

Voor complexere gevallen, waarbij metadata informatie kan bevatten over aangepaste klassen of andere types, is het nodig om expliciete markers of een schema in JSON op te nemen dat de datatypes beschrijft.

Voorbeeld met expliciete markers:

{
  "user": {
    "_type": "User",
    "name": "Alice",
    "registrationDate": {
      "_type": "Date",
      "value": "2023-10-26T12:00:00.000Z"
    }
  },
  "settings": {
    "theme": "dark"
  }
}

En de bijbehorende reviver:

class User {
  constructor(name, registrationDate) {
    this.name = name;
    this.registrationDate = registrationDate;
  }
}

const jsonWithMetadata = '{"user": {"_type": "User", "name": "Alice", "registrationDate": {"_type": "Date", "value": "2023-10-26T12:00:00.000Z"}}, "settings": {"theme": "dark"}}';

const restoredObjectWithMetadata = JSON.parse(jsonWithMetadata, (key, value) => {
  if (value && typeof value === 'object' && value._type) {
    switch (value._type) {
      case 'Date':
        return new Date(value.value);
      case 'User':
        return new User(value.name, new Date(value.registrationDate.value));
      default:
        return value;
    }
  }
  return value;
});

console.log(restoredObjectWithMetadata.user instanceof User); // true
console.log(restoredObjectWithMetadata.user.registrationDate instanceof Date); // true

Deze aanpak vereist voorafgaande overeenstemming over de structuur van de metadata in JSON (bijvoorbeeld het gebruik van de sleutel _type) en de implementatie van de herstel-logica in de reviver voor elk type. Voor complexe objecten, zoals instanties van aangepaste klassen met methoden, is een meer verfijnde aanpak nodig, mogelijk inclusief serialisatie en deserialisatie van methoden of het gebruik van gespecialiseerde bibliotheken. Echter, voor standaard types en eenvoudige datastructuren is reviver vrij effectief.