Мне неясно, как сериализация / десериализация должна работать на типизированных объектах в JavaScript.Например, у меня есть объект «MapLayer», который содержит различные члены и массивы.Я написал (но еще не протестировал) следующий код, чтобы попытаться его сериализовать:
MapLayer.prototype.serialize = function() {
var result = "{tileset:tilesets." + tilesets.getTilesetName(this.tileset) + ",columns:" + this.columns + ",rows:" + this.rows +
",offsetX:" + this.offsetX + ",offsetY:" + this.offsetY + ",currentX:" + this.currentX + ",currentY:" + this.currentY +
",scrollRateX:" + this.scrollRateX + ",scrollRateY:" + this.scrollRateY + ",virtualColumns:" + this.virtualColumns + ",virtualRows:" + this.virtualRows +
",tiles:\"" + this.encodeTileData2() + "\"";
for(key in this)
{
if(this[key] instanceof Sprite)
result += "," + key + ":" + this[key].serialize();
}
return result;
}
Мой вопрос заключается в том, как полученный объект должен десериализоваться как объект MapLayer, а не как универсальный объект.,И как все экземпляры Sprite должны быть десериализованы как спрайты?Должен ли я использовать «новый MapLayer ()» вместо «{}»?Или я просто должен включить свойства прототипа и конструктора объекта в сериализацию?Что-то еще я пропускаю?Я делаю это глупо?Есть 2 причины, по которым я не использую общий код сериализации / десериализации:
- Я хочу сериализовать данные тайла в оптимизированном формате, а не хранить строковое представление base-10 для каждой тайла,и все они должны быть разделены запятыми.
- Я не хочу сериализовать набор плиток как объект, который создается как новый объект во время десериализации, а скорее как ссылку на существующий объект.Возможно ли это с использованием кода, подобного предложенному выше?
Редактировать: Извините, что у меня нет правильной терминологии;JavaScript - один из моих менее опытных языков.Что я имею в виду, когда говорю «Типизированный объект» - это объект с конструктором.В этом примере мой конструктор:
function MapLayer(map, tileset, columns, rows, virtualColumns, virtualRows, offsetX, offsetY, scrollRateX, scrollRateY, priority, tileData) {
this.map = map;
this.tileset = tileset;
this.columns = columns;
this.rows = rows;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.currentX = offsetX;
this.currentY = offsetY;
this.scrollRateX = scrollRateX;
this.scrollRateY = scrollRateY;
if(tileData.length < columns * rows * 2)
this.tiles = DecodeData1(tileData);
else
this.tiles = DecodeData2(tileData);
this.virtualColumns = virtualColumns ? virtualColumns : columns;
this.virtualRows = virtualRows ? virtualRows : rows;
}
Редактировать 2: Взяв код из ответа Шиме Видаса, я добавил связанный объект под названием «Устройство»:
function Device( description, memory ) {
this.description = description;
this.memory = memory;
}
function Person( name, sex, age, devices ) {
this.name = name;
this.sex = sex;
this.age = age;
this.devices = devices;
}
Person.deserialize = function ( input ) {
var obj = JSON.parse( input );
return new Person( obj.name, obj.sex, obj.age, obj.devices );
};
var device = new Device( 'Blackberry', 64);
var device2 = new Device( 'Playstation 3', 600000);
var person = new Person( 'John', 'male', 25, [device, device2] );
var string = JSON.stringify(person);
console.log( string );
var person2 = Person.deserialize( string );
console.log( person2 );
console.log( person2 instanceof Person );
Теперь вопрос состоит в том, как лучше всего включить такие зависимые объекты, потому что еще раз «тип» (прототип?) Объекта теряется JSON.Вместо запуска конструктора, почему бы нам просто не изменить функции сериализации и десериализации, чтобы гарантировать, что объект должен быть сконструирован только один раз, а не создан и скопирован?
Person.prototype.serialize = function () {
var obj = this;
return '({ ' + Object.getOwnPropertyNames( this ).map( function ( key ) {
var value = obj[key];
if ( typeof value === 'string' ) { value = '"' + value + '"'; }
return key + ': ' + value;
}).join( ', ' ) + ',"__proto__":Person.prototype})';
};
Person.deserialize = function ( input ) {
return eval( input );
};
Редактировать 3: Другая проблема, с которой я столкнулся, заключается в том, что JSON не работает в IE9.Я использую этот тестовый файл:
<html>
<head>
<title>Script test</title>
<script language="javascript">
console.log(JSON);
</script>
</head>
</html>
И вывод консоли:
SCRIPT5009: 'JSON' is undefined
test.html, line 5 character 1
Редактировать 4: Чтобы исправить проблему JSON, я должен включить правильнуюТег DOCTYPE в начале.