Javascript 将自定义对象转换为JSON,然后再返回自定义对象?

Javascript 将自定义对象转换为JSON,然后再返回自定义对象?,javascript,json,object,Javascript,Json,Object,我见过与此非常相似的问题,但我不能确定这些问题是否得到了明确的回答——也许我有点糊涂,对不起 我想拥有自己对象的便利性(和清晰性),称之为CardboardBox()。它不包含代码,只包含数据。我想将其写入数据库,稍后再将其读回,但显然,读回时它是一个类型Object()。我所能想到的是要找出它曾经是什么: 有一个成员变量type,我将其设置为carboard\u BOX 实例化一个新的CarbardBox()并使用一个函数(在框中)将Object()的属性复制到新的CardboardBox()

我见过与此非常相似的问题,但我不能确定这些问题是否得到了明确的回答——也许我有点糊涂,对不起

我想拥有自己对象的便利性(和清晰性),称之为
CardboardBox()
。它不包含代码,只包含数据。我想将其写入数据库,稍后再将其读回,但显然,读回时它是一个类型
Object()
。我所能想到的是要找出它曾经是什么:

  • 有一个成员变量
    type
    ,我将其设置为carboard\u BOX
  • 实例化一个新的
    CarbardBox()
    并使用一个函数(在框中)将
    Object()的属性复制到新的
    CardboardBox()
    对象
  • 有更好的方法吗?我很确定我可以改变实际的类型

    先谢谢你。。。 史蒂夫

    [编辑]我的测试代码

    function CardboardBox(n) {
      this.name = n;
    }
    
    var box = new CardboardBox("My Box");
    send = JSON.stringify(box); // JSON CarboardBox()
    
    obj = JSON.parse(send, function fn(obj) { // Object() returned
      log("OB: "+obj.type);
      return obj.type === 'CardboardBox' ? new CardboardBox(obj) : CardboardBox; 
    });     
    console.log(obj);
    
    输出为:

    OB: undefined utils.js:40
    OB: undefined utils.js:40
    function CardboardBox(n) {
        this.name = n;
    } 
    

    一种可能的解决方案如下:

    function CardboardBox(n) {
      if(typeof(n) == 'string') {
        //build from name string
        this.name = n;
      } else {
        //build from object
        this.name = n.name;
      }
    
      //add in this object's "type" in a place
      //that is unlikely to exist in other JSON strings
      this.__type = 'CardboardBox';
    }
    
    var box = new CardboardBox("My Box");
    send = JSON.stringify(box), // JSON CarboardBox()
    obj = JSON.parse(send, function(key, val) {
      //if this is an object, and is CardboardBox
      if(typeof(val) === 'object' && val.__type === 'CardboardBox')
          return new CardboardBox(val);
    
      return val;
    
      //or if your object is in a context (like window), and there are many of
      //them that could be in there, you can do:
      //
      //if(typeof(val) === 'object' && context[val.__type])
      //    return new context[val.__type](val);
    });
    
    
    console.log(obj);
    
    基本上,将对象类型存储在稍后解析json时要查找的位置。如果有多个对象可以在单个范围内实例化,那么第二种解析方法可能更合适。这也将解释JSON中不是
    CarboardBox
    s的对象


    编辑下面是这个方法的一个例子。

    总的来说,你是正确的:Javascript没有任何内置的方式来序列化普通对象以外的任何东西,因此在反序列化JSON时,从JSON转到JSON不会生成特定的类。因此,您需要自己进行序列化/反序列化,或者使用提供一些支持的库

    我个人喜欢这个问题,因为它可以很好地处理序列化和反序列化。您定义了一个模型类,其中包括一个将其数据以序列化形式保存到服务器的方法,以及一个将其反序列化回模型的方法。这里的关键设计问题是,反序列化是在知道要反序列化到的模型的情况下执行的:

    • 您可以调用
      myModel.fetch()
      根据模型id从服务器获取数据,或者
    • 将一组新数据传递给模型构造函数:
      newmodel(serializedData)
      ,或
    • 将多个模型的数据数组传递给知道模型类型的集合:
      newmodelcollection(arrayOfSerializedData)
    主干网不做的是处理未知类型的类型转换数据。当我处理这个问题时,我通常会做一些类似于@Chad的响应的事情,但是使用一个中介;您可以将其视为代理模型或工厂:

    var classes = {
        CardboardBox: ...,
        AluminumBox: ...
    }
    
    function Deserializer(json) {
        // parse if you're actually dealing with a string
        var data = JSON.parse(json),
            // now look for some custom type flag - you'll need to set this yourself
            type = data.type,
            // class lookup, perhaps with a default
            Cls = classes[type] || DefaultType;
        return new Cls(data);
    }
    
    var obj = new Deserializer(send);
    obj instanceof CardboardBox; // should work
    

    尽管如此,这仍然依赖于一个自定义标志来切换类型——我不确定是否有办法解决这个问题。

    看看JSON.parse和JSON.stringify参数。可以对每个对象进行自定义回调
    JSON.parse(obj,fn);函数fn(obj){return obj.type=='a'?新的a(obj):a;}
    如果我有时间的话,我会写一个正确的答案。对不起,谢谢你的回复。非常感谢,但我现在有点困惑了。如果我在我的
    CardboardBox()
    上使用函数(fn),那么从
    JSON.parse()
    返回的是
    CarboardBox()
    的构造函数<代码>对象类型
    始终未定义。我想我遗漏了什么…@Steve:你必须设置
    。键入
    ,而且你没有正确使用参数(第一个参数不是建议的
    obj
    )。请参阅。为什么测试代码不设置
    类型
    成员?这就是为什么
    type
    是未定义的。是的,这几乎就是我的解决方案。我只是想知道有没有更好的办法。希望JavaScript有合适的类。我想我将以某种JavaBean类型的东西作为结束。不是JavaScript“没有合适的类”,而是JSON格式不支持自定义对象。不幸的是,你必须解决这个问题,据我所知,这(或一个变体)是实现它的唯一途径。即使它是使用主干或一些框架抽象出来的,它也只是在幕后做一些类似的事情。所有这些都是非常好的答案。谢谢我可能最终会编写自己的JSON包装器。如果在反序列化之后无法将对象放入正确的类中,代码将变得混乱,并且/或者我将在以后对对象进行额外的工作。
    var classes = {
        CardboardBox: ...,
        AluminumBox: ...
    }
    
    function Deserializer(json) {
        // parse if you're actually dealing with a string
        var data = JSON.parse(json),
            // now look for some custom type flag - you'll need to set this yourself
            type = data.type,
            // class lookup, perhaps with a default
            Cls = classes[type] || DefaultType;
        return new Cls(data);
    }
    
    var obj = new Deserializer(send);
    obj instanceof CardboardBox; // should work