2011-12-30 2 views
1

Это следующий вопрос к Javascript Serialization of Typed Objects. Это решение работает нормально для объектов, тип которых известен, но теперь у меня есть объект типа, который неизвестен кодом, который будет выполнять де-сериализацию. Существует базовый класс «Sprite», который имеет ряд свойств, которые необходимо сериализовать. Любое количество производных классов (таких как «Player» и «Platform» и т. Д.) Может быть получено из класса Sprite и добавлять свои собственные свойства. У меня также есть объект «MapLayer», который содержит коллекцию объектов, полученных из Sprite. Как я де-сериализую слой и все его спрайты, чтобы каждый спрайт имел правильный производный тип при завершении де-сериализации. Нужно ли использовать eval («new» + resultTypeName + parameterList)? Есть ли способ лучше?Как десериализовать объект JavaScript неизвестного производного класса

Подробнее: Базовый класс Sprite имеет жесткую кодировку, но все производные классы генерируются кодом. Я могу заставить генератор кода генерировать десериализационные функции для каждого производного класса, но как я могу их соответствующим образом назвать из функции десериализации универсальной базой? Существует только один класс MapLayer, и каким-то образом он должен потенциально вызвать функцию десериализации на всех классах, полученных из Sprite.

+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, которая обеспечивает десериализацию «классов» в том смысле, в котором вы знакомы в .net.

+0

Это единственный/лучший способ обратиться ко всем членам глобального пространства имен по имени: window []? – BlueMonkMN

+0

Вы можете создать новую переменную, содержащую ссылку на глобальное пространство имен. Но было бы более предпочтительным избегать «загрязнения» глобального пространства имен и хранить ссылки на вашу конструкторскую функцию в некоторой другой переменной. –

+0

При рассмотрении моего кода я обнаружил, что мой объект на самом деле не находится в глобальном пространстве имен. Однако я все еще обеспокоен тем, что, как представляется, нет никакого общего способа для неизвестного объекта десериализоваться, если, например, он существует в непредсказуемом пространстве имен. В .NET вы можете просто использовать двоичную сериализацию или отражение, чтобы получить полное имя типа, чтобы воссоздать объект того же типа, независимо от пространства имен. Если объект JavaScript в произвольном «пространстве имен» решает наследовать из сериализуемого класса, действительно ли нет возможности для общей десериализации? – BlueMonkMN

Смежные вопросы