web-dev-qa-db-fra.com

Sérialiser un objet JavaScript dans une chaîne JSON

J'ai ce prototype JavaScript:

Utils.MyClass1 = function(id, member) {
this.id = id;
this.member = member;
}

et je crée un nouvel objet:

var myobject = new MyClass1("5678999", "text");

Si je fais: 

console.log(JSON.stringify(myobject));

le résultat est:

{"id":"5678999", "member":"text"}

mais j'ai besoin que le type des objets soit inclus dans la chaîne JSON, comme ceci:

"MyClass1": { "id":"5678999", "member":"text"} 

Y at-il un moyen rapide de le faire en utilisant un cadre ou quelque chose? Ou dois-je implémenter une méthode toJson() dans la classe et le faire manuellement?

47
Kalamarico
var myobject = new MyClass1("5678999", "text");
var dto = { MyClass1: myobject };
console.log(JSON.stringify(dto));

MODIFIER:

JSON.stringify va chaîne tous les 'propriétés' de votre classe. Si vous souhaitez ne conserver que certains d’entre eux, vous pouvez les spécifier individuellement comme suit:

var dto = { MyClass1: {
    property1: myobject.property1,
    property2: myobject.property2
}};
61
Jakub Konecki

C'est juste JSON? Vous pouvez stringify() JSON:

var obj = {
    cons: [[String, 'some', 'somemore']],
    func: function(param, param2){
        param2.some = 'bla';
    }
};

var text = JSON.stringify(obj);

Et ré-analysez à nouveau JSON avec parse():

var myVar = JSON.parse(text);

Si vous avez des fonctions dans l'objet, utilisez ceci pour sérialiser: 

function objToString(obj, ndeep) {
  switch(typeof obj){
    case "string": return '"'+obj+'"';
    case "function": return obj.name || obj.toString();
    case "object":
      var indent = Array(ndeep||1).join('\t'), isArray = Array.isArray(obj);
      return ('{['[+isArray] + Object.keys(obj).map(function(key){
           return '\n\t' + indent +(isArray?'': key + ': ' )+ objToString(obj[key], (ndeep||1)+1);
         }).join(',') + '\n' + indent + '}]'[+isArray]).replace(/[\s\t\n]+(?=(?:[^\'"]*[\'"][^\'"]*[\'"])*[^\'"]*$)/g,'');
    default: return obj.toString();
  }
}

Exemples:

Sérialiser:

var text = objToString(obj); //To Serialize Object

Résultat:

"{cons:[[String,"some","somemore"]],func:function(param,param2){param2.some='bla';}}"

Désérialiser:

Var myObj = eval('('+text+')');//To UnSerialize 

Résultat:

Object {cons: Array[1], func: function, spoof: function}
11
MSS

Eh bien, le type d'un élément n'est pas sérialisé de manière standard, vous devez donc l'ajouter manuellement. Par exemple

var myobject = new MyClass1("5678999", "text");
var toJSONobject = { objectType: myobject.constructor, objectProperties: myobject };
console.log(JSON.stringify(toJSONobject));

Bonne chance!

edit: a changé le typeof en le .constructor correct. Voir https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor pour plus d'informations sur la propriété de constructeur pour Objects.

2
Willem Mulder

Cela pourrait être utile http://nanodeath.github.com/HydrateJS/https://github.com/nanodeath/HydrateJS

Utilisez hydrate.stringify pour sérialiser l'objet et hydrate.parse pour désérialiser.

2
dips

Vous pouvez utiliser une fonction nommée sur le constructeur. 

MyClass1 = function foo(id, member) {
    this.id = id;
    this.member = member;
}

var myobject = new MyClass1("5678999", "text");

console.log( myobject.constructor );

//function foo(id, member) {
//    this.id = id;
//    this.member = member;
//}

Vous pouvez utiliser une expression régulière pour analyser «foo» dans myobject.constructor et l'utiliser pour obtenir le nom.

1
Geuis
    function ArrayToObject( arr ) {
    var obj = {};
    for (var i = 0; i < arr.length; ++i){
        var name = arr[i].name;
        var value = arr[i].value;
        obj[name] = arr[i].value;
    }
    return obj;
    }

      var form_data = $('#my_form').serializeArray();
            form_data = ArrayToObject( form_data );
            form_data.action = event.target.id;
            form_data.target = event.target.dataset.event;
            console.log( form_data );
            $.post("/api/v1/control/", form_data, function( response ){
                console.log(response);
            }).done(function( response ) {
                $('#message_box').html('SUCCESS');
            })
            .fail(function(  ) { $('#message_box').html('FAIL'); })
            .always(function(  ) { /*$('#message_box').html('SUCCESS');*/ });
1

Vous trouverez ci-dessous un autre moyen d'utiliser des données JSON avec la fonction JSON.stringify ().

var Utils = {};
Utils.MyClass1 = function (id, member) {
    this.id = id;
    this.member = member;
}
var myobject = { MyClass1: new Utils.MyClass1("5678999", "text") };
alert(JSON.stringify(myobject));
1
Elias Hossain

J'avais quelques problèmes en utilisant les solutions ci-dessus avec un objet de type "tableau associatif". Ces solutions semblent conserver les valeurs, mais pas les noms réels des objets auxquels ces valeurs sont associées, ce qui peut entraîner des problèmes. Donc, j'ai mis en place les fonctions suivantes que j'utilise à la place:

function flattenAssocArr(object) {
  if(typeof object == "object") {
    var keys = [];
    keys[0] = "ASSOCARR";
    keys.Push(...Object.keys(object));
    var outArr = [];
    outArr[0] = keys;
    for(var i = 1; i < keys.length; i++) {
        outArr[i] = flattenAssocArr(object[keys[i]])
    }
    return outArr;
  } else {
    return object;
  }
}

function expandAssocArr(object) {
    if(typeof object !== "object")
        return object;
    var keys = object[0];
    var newObj = new Object();
    if(keys[0] === "ASSOCARR") {
        for(var i = 1; i < keys.length; i++) {
            newObj[keys[i]] = expandAssocArr(object[i])
        }
    }
    return newObj;
}

Notez que ceux-ci ne peuvent être utilisés avec aucun objet quelconque. En gros, il crée un nouveau tableau, stocke les clés en tant qu'élément 0, avec les données qui le suivent. Donc, si vous essayez de charger un tableau qui n'a pas été créé avec ces fonctions ayant l'élément 0 comme liste de clés, les résultats pourraient être ... intéressants :)

Je l'utilise comme ceci:

var objAsString = JSON.stringify(flattenAssocArr(globalDataset));
var strAsObject = expandAssocArr(JSON.parse(objAsString));
0
urza9814

J'ai résolu mon problème de cette manière, ce n'est pas la meilleure façon mais c'est intéressant de partager:

J'ai changé directement la bibliothèque json2.js (à l'opposé des meilleures pratiques ...), changé de méthode JSON.stringify () et dans la fonction str () lors de la lecture d'un objet, j'ai d'abord mis le typeof:

// Otherwise, iterate through all of the keys in the object.
// I have introduced speechModify variable.
var speechModify = false;
if(value.classname) {
    partial.Push('"' + value.classname + '":{');
    speechModify = true;
}

C'est uniquement pour ajouter un attribut classname dans mes classes. Et après itération, ajoute cette phrase:

if(speechModify)
    partial.Push("}");

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

v = partial.length === 0
    ? '{}'
    : gap
        ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
        : '{' + partial.join(',') + '}';
gap = mind;

v = v.replace("{,","{");
v = v.replace(",}", "}");
0
Kalamarico

Pour sérialiser un objet en chaîne, vous pouvez utiliser JSON.stringify():

var json_str = JSON.stringify(obj, null, 2); 
// here obj is the Object to serialize, 
// second parameter null for replacer (Optional), 
// 2 for space(optional)

voir ici pour plus de détails sur JSON.stringify () .

Encore une fois, chaîne JSON à un objet, utilisez JSON.parse():

var obj = JSON.parse(json_str);
0
Gautam Rai