[英]JSON Circular Object Type Reviver
我正在構建一個使用用戶可以操作和保存的自定義循環對象的Web應用程序游戲。 所有對象都連接到使用Circular-JSON存儲的圓形“播放器”對象。
該應用程序要求保留對象類型,但JSON不會這樣做。 我不能為每個單獨的對象聲明類型,因為玩家可能有幾百種不同類型的對象。 我已經看到了一些類型特定的reviver,但不是通用的或者可以使用圓形對象的。
例如:
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;
}
負載將本地存儲上的播放器替換為新播放器,但所有對象在此過程中都會丟失其類型,然后失去功能。
是否存在可行的復蘇? 可以寫一個嗎?
我想通用的問題是,有沒有辦法存儲和檢索圓形對象,同時保持類型?
@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);
您傳遞了密鑰和構造函數名稱(您甚至可以通過遵循約定來進一步簡化),在密鑰處解析對象,然后將其注入新的構造函數。 此后,您只需指定構造函數名稱的小寫版本。 您也可以遍歷值並找到'〜'。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.