Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类型化对象的Javascript序列化_Javascript_Json_Serialization - Fatal编程技术网

类型化对象的Javascript序列化

类型化对象的Javascript序列化,javascript,json,serialization,Javascript,Json,Serialization,我不清楚序列化/反序列化应该如何在JavaScript中的类型化对象上工作。例如,我有一个包含各种成员和数组的“MapLayer”对象。我已编写(但尚未测试)以下代码以尝试对其进行序列化: MapLayer.prototype.serialize = function() { var result = "{tileset:tilesets." + tilesets.getTilesetName(this.tileset) + ",columns:" + this.columns + ",r

我不清楚序列化/反序列化应该如何在JavaScript中的类型化对象上工作。例如,我有一个包含各种成员和数组的“MapLayer”对象。我已编写(但尚未测试)以下代码以尝试对其进行序列化:

MapLayer.prototype.serialize = function() {
   var result = "{tileset:tilesets." + tilesets.getTilesetName(this.tileset) + ",columns:" + this.columns + ",rows:" + this.rows + 
   ",offsetX:" + this.offsetX + ",offsetY:" + this.offsetY + ",currentX:" + this.currentX + ",currentY:" + this.currentY + 
   ",scrollRateX:" + this.scrollRateX + ",scrollRateY:" + this.scrollRateY + ",virtualColumns:" + this.virtualColumns + ",virtualRows:" + this.virtualRows +
   ",tiles:\"" + this.encodeTileData2() + "\"";
   for(key in this)
   {
      if(this[key] instanceof Sprite)
         result += "," + key + ":" + this[key].serialize();
   }
   return result;
}
我的问题是,如何将结果对象反序列化为MapLayer对象而不是通用对象。以及如何将所有精灵实例反序列化为精灵。我应该使用“new MapLayer()”而不是“{}”吗?或者我只是想在序列化中包含对象的原型和构造函数属性?我还缺什么?我这样做是不是很愚蠢?我不使用泛型序列化/反序列化代码有两个原因:

  • 我希望以优化的格式序列化磁贴数据,而不是为每个磁贴存储一个base-10字符串表示,并用逗号分隔它们
  • 我不想将tileset序列化为在反序列化期间构造为新对象的对象,而是作为对现有对象的引用。这是否可能使用我上面提出的代码
  • 编辑:请原谅我没有恰当的术语;JavaScript是我不太擅长的语言之一。我所说的“类型化对象”是指具有构造函数的对象。在本例中,我的构造函数是:

    function MapLayer(map, tileset, columns, rows, virtualColumns, virtualRows, offsetX, offsetY, scrollRateX, scrollRateY, priority, tileData) {
       this.map = map;
       this.tileset = tileset;
       this.columns = columns;
       this.rows = rows;
       this.offsetX = offsetX;
       this.offsetY = offsetY;
       this.currentX = offsetX;
       this.currentY = offsetY;
       this.scrollRateX = scrollRateX;
       this.scrollRateY = scrollRateY;
       if(tileData.length < columns * rows * 2)
          this.tiles = DecodeData1(tileData);
       else
          this.tiles = DecodeData2(tileData);
       this.virtualColumns = virtualColumns ? virtualColumns : columns;
       this.virtualRows = virtualRows ? virtualRows : rows;
    }
    
    现在的问题是如何最好地合并这些依赖对象,因为JSON再次丢失了对象的“类型”(原型?)。与其运行构造函数,不如简单地更改serialize和de-serialize函数,以确保对象只需要像这样构造一次,而不需要创建和复制

    Person.prototype.serialize = function () {
        var obj = this; 
        return '({ ' + Object.getOwnPropertyNames( this ).map( function ( key ) {
            var value = obj[key];
            if ( typeof value === 'string' ) { value = '"' + value + '"'; }
            return key + ': ' + value;
        }).join( ', ' ) + ',"__proto__":Person.prototype})'; 
    };
    
    Person.deserialize = function ( input ) {
        return eval( input );
    };
    
    编辑3: 我遇到的另一个问题是JSON在IE9中似乎不起作用。我正在使用此测试文件:

    <html>
    <head>
    <title>Script test</title>
    <script language="javascript">
    console.log(JSON);
    </script>
    </head>
    </html>
    
    编辑4:
    要更正JSON问题,我必须在开头包含正确的DOCTYPE标记。

    首先,这里是一个自定义序列化/反序列化的简单示例:

    function Person( name, sex, age ) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    
    Person.prototype.serialize = function () {
        var obj = this;
        return '{ ' + Object.getOwnPropertyNames( this ).map( function ( key ) {
            var value = obj[key];
            if ( typeof value === 'string' ) { value = '"' + value + '"'; }
            return '"' + key + '": ' + value;
        }).join( ', ' ) + ' }';
    };
    
    Person.deserialize = function ( input ) {
        var obj = JSON.parse( input );
        return new Person( obj.name, obj.sex, obj.age );
    };
    
    用法:

    首先,我们创建一个新的实例对象:

    var person = new Person( 'John', 'male', 25 );
    
    现在,我们使用
    Person.prototype.serialize
    方法将该对象序列化为字符串:

    var string = person.serialize();
    
    这将使用以下字符串:

    { "name": "John", "sex": "male", "age": 25 }
    
    最后,我们使用
    Person.deserialize
    static方法反序列化该字符串:

    var person2 = Person.deserialize( string );
    
    现在,
    person2
    Person
    的一个实例,它包含与原始
    Person
    实例相同的属性值

    现场演示:


    现在,尽管在任何情况下都需要
    Person.deserialize
    静态方法(它在内部使用
    JSON.parse
    ,并调用
    Person
    构造函数初始化新实例),但另一方面,
    Person.prototype.serialize
    方法,仅当内置的
    JSON.stringify
    静态方法不能满足要求时才需要

    在我上面的示例中,
    var string=JSON.stringify(person)
    也可以完成这项工作,因此不需要自定义序列化机制。请参见此处:但是,您的案例更复杂,因此您需要定义一个自定义序列化函数。

    如果您查看ST-JS()项目,它允许在服务器端用Java创建对象图,在JSON中序列化,并在客户端(Javascript)以类型化方式反序列化,也就是说,对象将使用其构造函数实例化,您可以对创建的对象调用方法

    要使用ST-JS,您应该使用Java编写您的客户机代码,这在Javascript中几乎是一对一的转换


    网站主页上的AJAX/JSON一章解释了如何在保留类型信息的同时解析JSON字符串。

    使用构造函数而不是“object”的对象。我不知道该怎么称呼它。啊,你指的是属于你自己的构造函数的对象(
    MapLayer
    Sprite
    ,等等)…我的建议是一个
    MapLayer.prototype.deserialize
    方法,它将接受一个字符串并返回一个
    MapLayer
    对象。我正在处理一个示例…那么在本例中请避免使用JSON?由
    JSON.stringify(yourMapLayerObj)
    返回的字符串是否符合您的要求?如果没有,那么您显然需要一个定制的stringify/parse解决方案……我已经更新了这个问题。为什么我们不设置
    \uuuuu proto\uuuu
    而不是调用构造函数呢?另一个问题是,如果我尝试在IE中使用JSON,我会得到一个错误“JSON未定义”。@BlueMonkMN因为
    \uuu proto\uuu
    是非标准的,不推荐使用。它从未在IE中实现过(将来也不会)。ECMAScript标准不提供任何方法来设置对象的原型链接。。。你正在使用哪个版本的IE?
    JSON
    对象是在IE8中添加的…@BlueMonkMN在IE中尝试
    console.log(JSON)
    。您应该在IE的控制台(F12->console选项卡)中获得
    '[object JSON]
    。@BlueMonkMN啊,这是因为您没有定义doctype。添加
    作为HTML文档的第一行。如果你不能定义一个有效的doctype,IE会进入怪癖模式…我想OP是在询问现有代码库使用的技术,而不是迁移到另一个框架。是的,你说得对。我指出的问题是,为了能够以通用方式反序列化“类型化”对象的图形(如编辑2中),您需要以某种方式存储有关“类型化对象”的元数据,即告诉反序列化器,“Person”的“devices”属性就是“Device”数组.如果你看一下我们的parseJSON函数(应该可以很容易地提取),它使用一个名为“typeDescription”的“静态”字段,这是一个简单的映射-我们的框架生成,但也可以手动创建。
    { "name": "John", "sex": "male", "age": 25 }
    
    var person2 = Person.deserialize( string );