【问题标题】:Serialize JavaScript object into JSON string将 JavaScript 对象序列化为 JSON 字符串
【发布时间】:2011-12-31 04:14:58
【问题描述】:

我有这个 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() 方法并手动执行?

【问题讨论】:

    标签: javascript json constructor


    【解决方案1】:
    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
    }};
    

    【讨论】:

    【解决方案2】:

    这只是 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}
    

    【讨论】:

      【解决方案3】:

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

      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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • HydrateJS 似乎可以正确处理函数序列化和循环引用。没有多少图书馆这样做! +1
        • 不幸的是,HydrateJS 的文档也很差,似乎没有维护
        【解决方案5】:

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

        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' 并使用它来获取名称。

        【讨论】:

          【解决方案6】:

          下面是我们使用 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));
          

          【讨论】:

            【解决方案7】:
                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');*/ });
            

            【讨论】:

              【解决方案8】:

              我在使用上述解决方案和“关联数组”类型对象时遇到了一些问题。这些解决方案似乎保留了值,但它们不保留与这些值关联的对象的实际名称,这可能会导致一些问题。所以我把我正在使用的以下函数放在一起:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2019-02-09
                • 1970-01-01
                • 2014-01-04
                • 2020-02-03
                • 1970-01-01
                • 2012-04-24
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多