web-dev-qa-db-fra.com

Comment sérialiser et désérialiser des objets Javascript?

J'ai besoin de sérialiser et de désérialiser des objets Javascript pour les stocker dans une base de données. 

Notez que ces objets contiennent des fonctions, je ne peux donc pas les stocker en tant que JSON, donc je ne peux pas utiliser json2.js.

Quel est l'état de l'art dans la [de] sérialisation des objets javascript (en javascript bien sûr).

Merci, Stewart

31
Stewart Johnson

En général, il n'y a aucun moyen (dans un navigateur), donc sérialisez les objets avec des fonctions qui leur sont attachées, car chaque fonction a une référence à sa portée externe. Si la fonction fait référence à l'une de ces variables, elles n'existeront plus lorsque vous la désérialiserez.

Ce que je voudrais est d'utiliser les fonctions JSON.stringify et JSON.parse intégrées (ou json2.js) avec les paramètres replacer et reviver. Voici un exemple partiel de la façon dont cela fonctionnerait:

JSON.stringify(yourObject, function(name, value) {
    if (value instanceof LatLng) { // Could also check the name if you want
        return 'LatLng(' + value.lat() + ',' + value.lng() + ')';
    }
    else if (...) {
        // Some other type that needs custom serialization
    }
    else {
        return value;
    }
});

JSON.parse(jsonString, function(name, value) {
    if (/^LatLng\(/.test(value)) { // Checking the name would be safer
        var match = /LatLng\(([^,]+),([^,]+)\)/.exec(value);
        return new LatLng(match[1], match[2]);
    }
    else if (...) {
        ...
    }
    else {
        return value;
    }
});

Vous pouvez utiliser le format de sérialisation de votre choix dans vos types personnalisés. Le format "LatLng (latitude, longitude)" n’est qu’un moyen de le faire. Vous pouvez même renvoyer un objet javascript pouvant être sérialisé en JSON de manière native.

27
Matthew Crumley

Vous ne voulez pas sérialiser la logique telle que des fonctions.

Si vous devez mettre à jour vos fonctions logic/js à l'avenir, vous ne voulez pas (toujours) que l'ancienne logique soit chargée de nouveau avec les données. Il faut se méfier.

10
lknox

utilisez gserializer:

http://www.onegeek.com.au/articles/programming/javascript-serialization.php

le code dans google:

http://code.google.com/p/gserializer/

GSerializer est une bibliothèque javascript pour sérialiser/désérialiser javascript objets à et de chaînes, pour persistance à dire, un cookie. Contrairement à de nombreuses autres implémentations, GSerializer peut également sérialiser fonctions et notation non-JSON.

7
Haim Evgi

Sur Node.js, il y a aussi le paquet JASON .

Voici l'exemple:

var JASON = require("JASON");

str = JASON.stringify(obj);
obj = JASON.parse(str);

Installez le package en: npm install JASON.

1
prototype

Si vous utilisez des versions ES6 de Node, vous pouvez extraire un petit paquet que j'ai écrit et intitulé JSOFF . C'est le format JavaScript Object-Function; un remplacement immédiat pour JSON qui gère les fonctions.

C’est très simple et très petit, Babeljs ou Browserify sont donc vos amis.

Installez via: npm install jsoff ou yarn add jsoff.

Voici l'exemple pour créer un objet avec des fonctions:

const JSOFF  = require('jsoff');

var obj = {
  abc: 123,
  def: function (a,b) { return a * 2 + b * 3; },
  ghi: a => { return a * 2 },
  jkl: (a,b) => { return ((d,e) => { return a*d + b*e })(2,4) }
};

var str = JSOFF.stringify(obj);
// str is now:  
// '{"abc":123,"def":"function (a,b) { return a * 2 + b * 3; }","ghi":"a => { return a * 2 }","jkl":"(a,b) => { return ((d,e) => { return a*d + b*e })(2,4) }"}');
});

var clone = JSOFF.parse(str);
clone.def(10,5)   // 35
clone.ghi(5)      // 10
clone.jkl(10,20)  // 100
1
Sir Robert

Je ne voudrais pas sérialiser les fonctions JS pour des raisons de sécurité. Grâce à une API publique, toutes sortes de problèmes peuvent être envoyés à la base de données. En ce qui concerne la désérialisation, j'ai une approche différente. Je mélange les objets de modèle définis côté client avec les données provenant de JSON. J'ai un petit outil pour le faire, jetez un oeil sur GitHub à khayll/jsonmix .

JsonMix fournit une sorte de désérialisation de JSON en objets JavaScript complets avec des fonctions.

Cela ressemblerait à quelque chose:

//model definition (just an example)

var LatLng = function() {}
LatLng.prototype.getMapTypeId = function() {
   return this.mapTypeId;
}

//deserializing done like this
var result = JSMix(jsonString).withObject(LatLng.prototype, "latLngs").build();

//all items in the latLngs collection have the functions coming from the model
console.log(result.latLngs[5].getMapTypeId());
0
fishgen