将JavaScript对象序列化为JSON字符串

时间:2011-11-17 09:26:56

标签: javascript json constructor

我有这个JavaScript原型:

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

我创建了一个新对象:

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

如果我这样做:

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

结果是:

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

但我需要包含在JSON字符串中的对象类型,如下所示:

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

使用框架或其他东西有快速的方法吗?或者我是否需要在类中实现toJson()方法并手动执行?

9 个答案:

答案 0 :(得分:63)

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

编辑:

JSON.stringify会对您班级的所有'属性'进行字符串化。如果您只想保留其中一些,可以单独指定它们:

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

答案 1 :(得分:11)

它只是JSON?你可以stringify() JSON:

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

var text = JSON.stringify(obj);

使用parse()再次解析JSON:

var myVar = JSON.parse(text);

如果对象中有函数,请使用此函数序列化:

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();
  }
}

示例:

序列化:

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

结果:

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

反序列化:

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

结果:

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

答案 2 :(得分:2)

嗯,元素的类型没有标准序列化,所以你应该手动添加它。例如

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

编辑:将typeof更改为正确的.constructor。有关Objects的构造函数属性的详细信息,请参阅https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor

答案 3 :(得分:2)

这可能很有用。 http://nanodeath.github.com/HydrateJS/ https://github.com/nanodeath/HydrateJS

使用hydrate.stringify序列化对象,使用hydrate.parse进行反序列化。

答案 4 :(得分:1)

您可以在构造函数上使用命名函数。

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;
//}

您可以使用正则表达式从myobject.constructor中解析出'foo'并使用它来获取名称。

答案 5 :(得分:1)

下面是我们使用JSON.stringify()函数

获取JSON数据的另一种方法
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));

答案 6 :(得分:1)

    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');*/ });

答案 7 :(得分:0)

我以这种方式解决了我的问题,显然不是最好的方式,但分享很有意思:

我直接更改了json2.js库(与最佳实践相反...),更改了方法JSON.stringify()和str()函数,当我读取第一个类型的对象时:

// 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;
}

这只是在我的类中添加classname属性。在迭代之后,添加以下句子:

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(",}", "}");

答案 8 :(得分:0)

在使用上述解决方案和“关联数组”类型对象时,我遇到了一些问题。这些解决方案似乎保留了这些值,但它们并未保留那些值所关联的对象的实际名称,这可能会引起一些问题。因此,我将以下正在使用的功能放在一起:

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;
}

请注意,这些对象不能与任何任意对象一起使用-基本上,它将创建一个新数组,将键存储为元素0,其后跟随数据。因此,如果您尝试加载未使用这些将元素0作为键列表的函数创建的数组,则结果可能会...很有趣:)

我正在这样使用它:

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