Comment dois-je persister un ES6 Carte dans localstorage (ou ailleurs)?
var a = new Map([[ 'a', 1 ]]);
a.get('a') //1
var forStorageSomewhere = JSON.stringify(a);
//Store, in my case, in localStorage.
//Later:
var a = JSON.parse(forStorageSomewhere);
a.get('a') //TypeError: undefined is not a function
Malheureusement JSON.stringify(a);
retourne simplement '{}', ce qui signifie un devient un objet vide quand restauré.
J'ai trouvé es6-mapify qui permet de up/down-conversion entre une Carte et un simple objet, de sorte que pourrait être une solution, mais j'espérais que j'aurais besoin de recourir à une dépendance externe simplement persister ma carte.
Vous devez vous connecter pour publier un commentaire.
En supposant que les deux vos clés et vos valeurs sont serialisable,
devrait fonctionner. Pour l'inverse, l'utilisation
.entries()
n'était pas nécessaire; ce que semble faire la même chose:localStorage.myMap = JSON.stringify(Array.from(map));
[Symbol.iterator]
queArray.from
utilise est le même que.entries
sur une Carte, mais je voulais le préciser, de sorte qu'il est évident que nous sommes à l'aide d'un itérateur ici.Généralement, la sérialisation n'est utile que si cette propriété détient
où
a ≈ b
pourrait être défini commeserialize(a) === serialize(b)
.C'est satisfait lors de la sérialisation d'un objet JSON:
Et cela fonctionne parce que les propriétés ne peuvent être des chaînes de caractères, qui peut être sans perte sérialisé dans les chaînes.
Cependant, ES6 cartes permettent de valeurs arbitraires que les clés. C'est problématique parce que, les objets sont identifiés de manière unique par référence, et non leurs données. Et lors de la sérialisation d'objets, vous perdez les références.
Donc je dirais en général, il n'est pas possible à le faire d'une manière utile.
Et pour les cas où il serait, très probablement, vous pouvez utilisez un simple objet au lieu d'une carte. Cela permettra également de ces avantages:
Construction de Oriol est réponse, nous pouvons faire un peu mieux. On peut encore utiliser des références d'objet pour les clés tant que l'on est racine primitive ou l'entrée dans la carte, et chaque objet clé peut être transitivement trouvés à partir de la racine de la clé.
Modifiant Oriol l'exemple de l'utilisation de Douglas Crockford de JSON.decycle et JSON.retrocycle nous pouvons créer une carte qui gère ce cas:
Decycle et retrocycle faire il possible d'encoder cyclique des structures et des dags en JSON. Ceci est utile si nous voulons établir des relations entre des objets, sans créer de nouvelles propriétés sur les objets eux-mêmes, ou que vous voulez de façon interchangeable concernent des primitives pour les objets et vice-versa, à l'aide d'un ES6 Carte.
L'un écueil, c'est que nous ne peut pas utiliser la clé d'origine de l'objet pour la nouvelle carte (
map3.get(key);
serait de retour indéfini). Toutefois, le maintien de la clé d'origine de référence, mais une nouvelle analysé JSON carte semble être un cas très improbable à jamais.Propre comme un coup de sifflet:
let deserialized = new Map(JSON.parse(serialisedMap));
La accepté de répondre échoue lorsque vous avez des multiples dimensions des Cartes. On devrait toujours garder à l'esprit que, une Carte objet peut prendre une autre Carte de l'objet comme une clé ou une valeur.
Donc une meilleure et plus sûre de la manipulation de ce travail pourrait être comme suit;
Une fois que vous avez cet outil, vous pouvez toujours faire comme;
Si vous implémentez votre propre
de la méthode toJSON()
la fonctionclass
les objets que vous avez alors juste régulières vieuxJSON.stringify()
tout fonctionne!Map
s avecArray
s pour les touches?Map
s avec d'autresMap
comme valeurs? UnMap
à l'intérieur d'un régulierObject
? Peut-être même votre propre classe; facile.Que c'est!
prototype de la manipulation est ici nécessaire. Vous pouvez aller autour de l'ajout de
toJSON()
manuellement tous vos non-standard des trucs, mais vraiment, vous êtes tout simplement en évitant la puissance de la JSDÉMO
sorties:
Deserialising tout le chemin du retour à la vraie
Map
s n'est pas aussi automatique, si. À l'aide de la chaîne résultante, je vais refaire les cartes pour tirer une valeur:sorties
C'est un peu brouillon, mais avec un peu de la magie de la sauce vous pouvez faire deserialisation automagic trop.
Maintenant le JSON est
Et deserialising et l'utilisation est très simple avec notre
Map.fromJSON
sorties (et pas
new Map()
s)DÉMO
Une chose qui est à gauche outis que la Carte est un COMMANDÉ structure - c'est à dire lors de l'itération le premier élément entré serait la première liste.
C'est PAS comme un Objet Javascript. J'ai ce type de structure (j'ai donc utilisé la Carte), puis de trouver que le JSON.stringify ne fonctionne pas est douloureux (mais compréhensible).
J'ai fini par faire un " value_to_json fonction, ce qui signifie que l'analyse de TOUT le
à l'aide de JSON.stringify seulement pour les plus de base "types".
Malheureusement sous-classement, CARTE, avec un .la méthode toJSON() ne fonctionne pas comme il l'exclut pas une valeur d'un JSON_string. Aussi il est considéré comme l'héritage.
Mon cas d'utilisation serait exceptionnel si.
connexes:
JS: