【问题标题】:How to deserialize JavaScript object of unknown derived class如何反序列化未知派生类的 JavaScript 对象
【发布时间】:2011-12-30 18:22:04
【问题描述】:

这是Javascript Serialization of Typed Objects 的后续问题。该解决方案适用于类型已知的对象,但现在我有一个类型为将执行反序列化的代码未知的对象。有一个基类“Sprite”,它有许多需要序列化的属性。任何数量的派生类(例如“播放器”和“平台”等)都可以从 Sprite 类派生并添加它们自己的属性。我还有一个“MapLayer”对象,其中包含一组 Sprite 派生对象。如何反序列化图层及其所有精灵,以便在反序列化完成后每个精灵都将具有正确的派生类型。我需要使用 eval("new" + derivedTypeName + parameterList) 吗?有没有更好的办法?

更多详情: Sprite 基类是硬编码的,但所有派生类都是生成代码。我可以让代码生成器为每个派生类生成反序列化函数,但是如何从通用基类反序列化函数中适当地调用它们呢?只有一个 MapLayer 类,它必须以某种方式潜在地调用从 Sprite 派生的所有类的反序列化函数。

【问题讨论】:

  • 考虑将其归结为本质。您引用了另一个问题,但您继续描述了与该问题不匹配的场景(例如,您询问的是 new,它不用于反序列化)
  • @KenBrowning "new" 用于该问题的建议答案。

标签: javascript json serialization


【解决方案1】:

为了调用派生对象的构造函数,您首先需要知道要调用哪个构造函数。您没有详细说明您当前如何在序列化有效负载中对​​该类型信息进行编码,因此假设您有以下内容:

var MyDerivedType = function () {...};
MyDerivedType.prototype.__derivedTypeName = 'MyDerivedType';
MyDerivedType.deserialize = function ( input ) {
    var obj = JSON.parse( input );
    return new MyDerivedType( obj );
};

如果您没有将派生类型分配给全局范围,那么您需要能够在反序列化时处理它们。这是将它们存储在 Sprite 构造函数本身的示例:

Sprite.derivedTypes = Sprite.derivedTypes || {};
Sprite.derivedTypes['MyDerivedType'] = MyDerivedType;

然后你可以避免使用eval 并像这样调用适当的反序列化器:

Sprite.deserialize = function(input) {

    // json parse the data string to pull out our derived type
    var o = JSON.parse(input);

    // delegate to the derived type's deserialize method
    return Sprite.derivedTypes[o.__derivedTypeName].deserialize(input);
};

JavaScript/浏览器 js 环境没有任何内置功能可以为您在 .net 中熟悉的意义上的“类”提供反序列化。

【讨论】:

  • 这是按名称引用全局命名空间所有成员的唯一/最佳方式:window[]?
  • 您可以创建一个新变量来保存对全局命名空间的引用。但更可取的是避免“污染”全局命名空间并将对构造函数的引用存储在其他变量中。
  • 在查看我的代码时,我发现我的对象实际上不在全局命名空间中。但是,我仍然感到困扰的是,如果未知对象存在于不可预测的命名空间中,似乎没有通用的方法来反序列化自身。在 .NET 中,您可以简单地使用二进制序列化或反射来检索类型的完全限定名称,以便重构相同类型的对象,而不管命名空间如何。如果任意“命名空间”中的 JavaScript 对象决定从可序列化的类继承,是否真的没有泛型反序列化的可能性?
  • JavaScript 对象不存在于命名空间中。变量存在于某个范围内。如果你想解决你的构造函数(我相信你最初的问题是问的),那么对它们的引用需要在你的代码执行的任何范围内都是可寻址的。你熟悉 JSON.stringify/parse 吗? json.org/js.html
  • 好吧,这是我的最后一次尝试。如果您正在寻找类似 .net 反序列化的东西,它不存在。您已经在构建自己的序列化机制。如果您需要它来解释派生类型,那么您必须对其进行编程。
猜你喜欢
  • 2013-07-11
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多