Мне неясно, как сериализация / десериализация должна работать с типизированными объектами в 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 для десериализации в виде спрайтов. Должен ли я использовать «new MapLayer ()» вместо «{}»? Или я просто должен включить свойства прототипа и конструктора объекта в сериализацию? Что-нибудь еще мне не хватает? Я делаю это глупо? Есть 2 причины, по которым я не использую общий код сериализации / десериализации:
Изменить: Извините за отсутствие правильной терминологии; 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.