2011-12-30 110 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