2011-12-30 58 views
1

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

更多详细信息: Sprite基类是硬编码的,但所有的派生类都是生成的代码。我可以让代码生成器为每个派生类生成反序列化函数,但是如何从泛型基类反序列化函数中适当地调用它们?只有一个MapLayer类,不知何故,它必须潜在地调用从Sprite派生的所有类的反序列化函数。

+0

考虑将其降低到其本质。你引用另一个问题,但是你继续描述一个不符合该问题的场景(例如,你问的是'new',它不用于反序列化) – 2011-12-30 18:54:53

+0

@KenBrowning在建议的答案中使用“new”这个问题。 – BlueMonkMN 2011-12-31 02:08:24

回答

2

为了调用派生对象的构造函数,你首先需要知道你想调用哪个构造函数。你不给你是如何编码目前在连载有效载荷类型信息的细节,让我们说你有类似以下内容:

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中熟悉的意义上的“类”的反序列化。

+0

这是按名称引用全局名称空间的所有成员的唯一/最佳方法:window []? – BlueMonkMN 2011-12-31 02:13:01

+0

您可以创建一个新变量来保存对全局名称空间的引用。但是更好的做法是避免“污染”全局名称空间并在其他变量中存储对构造函数的引用。 – 2011-12-31 05:34:02

+0

在审查我的代码时,我发现我的对象实际上不在全局名称空间中。然而,我仍然感到困惑的是,如果一个未知的对象存在于不可预知的命名空间中,那么似乎没有通用的方式让未知的对象反序列化。在.NET中,您可以简单地使用二进制序列化或反射来检索类型的完全限定名称,以便重构同一类型的对象,而不管命名空间如何。如果任意“命名空间”中的JavaScript对象决定从可序列化类继承,那么真的不可能使用泛型反序列化? – BlueMonkMN 2011-12-31 08:42:05