我正在构建一个使用用户可以操作和保存的自定义循环对象的Web应用程序游戏。所有对象都连接到一个圆形播放器'使用Circular-JSON存储的对象。
应用程序要求保留对象类型,但JSON不会这样做。我不能为每个单独的对象声明类型,因为玩家可能有几百种不同类型的对象。我已经看到了一些类型特定的复兴,但不是通用的或与圆形对象一起使用的复活。
例如:
function Room(name, description){
this.type = "room";
this.name = name;
this.description = description;
this.roomItems = [/*array of items randomly set*/];
this.exits = [/*array of rooms set */];
}
function Item(name, description, weight){
this.type = "item";
this.name = name;
this.description = description;
this.weight = weight;
this.components = [/*array of items*/];
this.contents = [];
this.setContents = function(item){
this.contents.push(item);
this.weight += item.weight;
}
}
function Player(startroom){
this.type = "player"
this.weightLimit = 20;
this.totalWeight = 0;
this.currentRoom = startroom; //this is a room
this.playerItems = [/* An array of Items */];
this.moveCount = 0;
}
该应用通过以下方式保存并加载:
function saveGame(){
var d = new Date()
player.lastsave = d.toISOString();
localStorage.setItem('player', CircularJSON.stringify(player));
}
function loadGame(){
declareStart(); //loads the same as a start
player = CircularJSON.parse(localStorage.getItem('player', reviver));
}
我尝试的复活如下:
function reviver(k, v){
switch (v.type) {
case "room":
$.extend(v, Room.prototype);
break;
case "item":
$.extend(v, Item.prototype);
break;
case "player":
$.extend(v, Player.prototype);
break;
}
return v;
}
加载使用本地存储上的播放器替换新播放器,但所有对象在此过程中都会丢失其类型,然后失去功能。
是否存在可行的复兴?可以写一个吗?
我想通用的问题是,有没有办法在保持类型的同时存储和检索圆形对象?
答案 0 :(得分:1)
@kahjav你绝对可以使用Object.create
来恢复类型,使用构造函数方法的名称和内省。使用在一个键上命名循环引用的约定,该键与构造函数的小写名称相同。请看我的主旨:
https://gist.github.com/jameswomack/6e6462f9c6ae5d9b9072
由于CircularJSON模块的创建方式,您无法仅使用CircularJSON保留父对象及其循环引用的类型。
基本上是一个两步过程
function get(key, Proto) {
var result = JSON.parse(this.store[key]);
return key === Proto.name.toLowerCase() ? reviveFromJSONResult(result, Proto) : result;
}
function reviveFromJSONResult(result, Proto) {
var value = Object.create(Proto);
for (var key in result) {
value[key] = result[key];
}
value[Proto.name.toLowerCase()] && (value[Proto.name.toLowerCase()] = value);
return value;
}
var person = get('person', Person);
传递密钥和构造函数名称(您甚至可以通过遵循约定来进一步简化),在密钥处解析对象,然后将其注入新的构造函数。此后,您只需指定构造函数名称的小写版本。您也可以遍历这些值并找到'〜'。