2011-12-30 9 views
1

これはJavascript Serialization of Typed Objectsへのフォローアップの質問です。そのソリューションは、型がわかっているオブジェクトに対しては正常に機能しますが、現在、非直列化を実行するコードでは不明な型のオブジェクトがあります。シリアライズする必要があるいくつかのプロパティを持つ基本クラス "スプライト"があります。任意の数の派生クラス(「Player」や「Platform」など)は、Spriteクラスから派生し、独自のプロパティを追加できます。私はまた、Sprite派生オブジェクトのコレクションを含む "MapLayer"オブジェクトを持っています。デシリアライゼーションが完了したときに、各スプライトが正しい派生型になるように、レイヤーとそのすべてのスプライトをデシリアライズするにはどうすればよいですか。 eval( "new" + derivedTypeName + parameterList)を使用する必要がありますか?より良い方法がありますか?未知の派生クラスのJavaScriptオブジェクトを逆シリアル化する方法

詳細: Sprite基本クラスはハードコードされていますが、すべての派生クラスは生成コードです。私は、コードジェネレータがすべての派生クラスに対して関数deserializeを生成するようにすることができますが、ジェネリックベースクラスの逆シリアル化関数からそれらを適切に呼び出す方法はありますか? MapLayerクラスは1つだけです。スプライトから派生したすべてのクラスでdeserialize関数を呼び出す必要があります。

+0

これを本質的に沸騰させることを検討してください。あなたは別の質問を参照しますが、その質問と一致しないシナリオを記述することになります(たとえば、非直列化では使用されない 'new'について質問しています)。 –

+0

@KenBrowning" new "その質問に。 – BlueMonkMN

答えて

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環境では、「クラス」に直列化解除を提供します。つまり、「ネット」に精通しているという意味です。

+0

これはグローバル名前空間のすべてのメンバーを名前で参照する唯一の/最良の方法です:window []? – BlueMonkMN

+0

グローバル名前空間への参照を保持する新しい変数を作成できます。しかし、グローバル名前空間を "汚染する"ことを避け、コンストラクタ関数への参照を他の変数に格納する方がより好ましいでしょう。 –

+0

私のコードを見て、私は自分のオブジェクトが実際にグローバル名前空間にないことを発見しました。しかし、未知のオブジェクトが、例えば、予測できない名前空間に存在する場合に、それ自体を逆直列化する一般的な方法がないように思えるのは、まだ悩んでいます。 .NETでは、バイナリのシリアル化またはリフレクションを使用して、型の完全修飾名を取得して、名前空間に関係なく同じ型のオブジェクトを再構成することができます。任意の「名前空間」内のJavaScriptオブジェクトが直列化可能なクラスから継承することを決定した場合、ジェネリックの直列化の可能性はありませんか? – BlueMonkMN

関連する問題