JSON循环对象类型恢复器
JSON Circular Object Type Reviver
我正在构建一个使用用户可以操作和保存的自定义圆形对象的web应用游戏。所有的对象都连接到一个使用circular - json存储的圆形'player'对象。
应用程序要求保留对象类型,但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;
}
加载用本地存储上的播放器替换新播放器,但在此过程中所有对象都失去了它们的类型,从而失去了功能。
是否存在有效的恢复器?有可能写一篇吗?
我猜一般的问题是,是否有一种方法来存储和检索循环对象,同时保持类型?
@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);
传递键和构造函数名称(您甚至可以通过遵循约定进一步简化此操作),在键处解析对象,然后将其注入新的构造函数。此后,只需将构造函数名称的小写版本赋值即可。您还可以遍历这些值并找到'~'。
相关文章:
- 为什么会出现错误;未捕获的类型错误:undefined不是函数;
- 如何在DOM元素上按类型构建此函数
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- YUI3 IO实用程序是否可以根据给定的内容类型标头值自动序列化数据
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- 如何从querySelectorAll中获取按钮类型
- 如何在输入字段中的按钮的帮助下打开日历,该字段的类型为“=”;日期”;
- 如何将具有文本类型值的var放入jQuery函数中
- 如何临时暂停浏览器渲染,然后恢复整个页面
- javascript解释器如何理解变量的数据类型
- 可变大小的JavaScript字符串如何成为基元类型
- NodeJS-readline暂停和恢复事件发射器(逐行读取)
- AngularJS指令只识别双向绑定类型
- 在<输入类型=“;文件“/>
- 从查询字符串参数推断出正确的数据类型
- 谷歌地图劫持了iphone's滚动(触摸事件)-如何恢复
- 未捕获的类型错误:无法读取属性'删除'的未定义
- 通过按钮/类型=“提交”行为恢复默认表单提交
- 如何为可恢复.js上传程序指定文件类型