Sobes.tech
Middle+

Cum se pot recupera obiectele din JSON astfel încât metadatele să fie păstrate?

sobes.tech AI

Răspuns de la AI

Pentru a restaura obiecte cu metadatele salvate din JSON, se poate folosi metoda JSON.parse() în combinație cu o funcție reviver. Reviver este o funcție opțională care este apelată pentru fiecare pereche cheie-valoare în timpul analizei JSON. Aceasta permite modificarea valorilor decodificate înainte de a fi returnate.

Exemplu de utilizare a reviver pentru păstrarea tipului:

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

Pentru cazuri mai complexe, în care metadatele pot include informații despre clase personalizate sau alte tipuri, este necesar să se includă markeri expliciți sau un schelet în JSON care să descrie tipurile de date.

Exemplu cu markeri expliciți:

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

Și reviver-ul corespunzător:

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

Această metodă necesită un acord prealabil asupra structurii metadatelor în JSON (de exemplu, utilizarea cheii _type) și implementarea logicii de restaurare în reviver pentru fiecare tip. Pentru obiecte complexe, cum ar fi instanțe ale claselor personalizate cu metode, va fi nevoie de o abordare mai sofisticată, posibil incluzând serializarea și deserializarea metodelor separat sau utilizarea bibliotecilor specializate. Cu toate acestea, pentru tipuri standard și structuri de date simple, reviver-ul este destul de eficient.