【发布时间】:2020-05-16 13:13:22
【问题描述】:
这是我的情况:我正在使用 MEAN 堆栈,在我的 Angular 前端,我正在创建类的实例并将它们放入一个数组数组中,这些数组都在一个 gameMap/mapData 对象中。然后我通过套接字连接将该对象字符串化并发送到我的后端,后端将该对象广播给其他连接的客户端,以便他们可以看到当前的游戏状态。
似乎其他对 JSON.parse() 有问题的人都希望它实例化类,但我遇到了相反的问题。当客户端通过套接字接收到这个游戏对象然后尝试 JSON.parse() 对象时,它似乎是自动从数据中实例化类,这导致在这些类上运行构造函数的问题,用构造函数默认值。如何阻止 JSON.parse 实例化这些类,而让它只创建具有类型的对象?
为了说明我在我的字符串化 JSON 对象中获得了正确的数据,但问题是当它被解析时,我在传入数据的 JSON.parse() 之前和之后放置了一个 console.log。此代码如下所示:
console.log('got existing map data, beginning processing:', mapDataRaw);
var mapData2 = JSON.parse(mapDataRaw);
console.log('parsed mapData:', mapData2);
在第一个控制台日志中,我得到了正确的更改值,如下所示(编辑并缩短了返回的对象,因为它很大):
{"location":{"row":1,"col":0,"rotate":180,"transform":"rotate(180deg)"},"hp":50,"speed":4,"range":6,"ammo":0,"shieldHP":0,"size":50,"border":"","team":"blue","moved":false,"imgAlpha":"1","name":"Fighter","missile":{"firing":true,"target":{"row":4,"col":3}},"img":"assets/img/playerShip1_blue.png","imgTop":{"img":"assets/img/Power-ups/pill_yellow.png","alpha":1,"transform":"","size":22}}
如您所见,弹药设置为 0,而在导弹属性中,射击属性设置为 true。但是,这是解析后控制台日志中此对象的部分:
0: Fighter
location: {row: 1, col: 0, rotate: 180, transform: "rotate(180deg)"}
hp: 50
speed: 4
range: 6
ammo: 1
shieldHP: 0
size: 50
border: ""
team: "blue"
moved: false
imgAlpha: "1"
name: "Fighter"
missile: {firing: false, target: {…}}
img: "assets/img/playerShip1_blue.png"
__proto__: BaseObj
注意弹药是1,在属性导弹中,发射属性是假的。这些都是不正确的,并且是这些值在游戏开始时的默认值。另请注意,它在数组的索引 0 处显示“Fighter”,这是类的名称。当原始字符串化对象属性中的任何地方似乎都没有说明时,JSON.parse() 到底是如何知道将其创建为 Fighter 类的实例的(我将“名称”设置为类名,但我尝试将其更改为 'unitName' 以防 'name' 是一些内置的类名并且没有改变任何东西)?我可以设置什么选项让 JSON 将这些对象解析为常规对象而不是类的实例?我已经编写了将这些对象中的值复制到客户端上的实际类对象实例中的代码,但是如果我从中复制的值已被默认覆盖,这将不起作用!
【问题讨论】:
-
JSON.parse()绝对没有实例化任何东西。不过我不知道发生了什么,我唯一能想到的就是您看到的实时输出已更新。如果你这样做console.log('parsed mapData:', JSON.stringify(mapData2));会发生什么? -
理论上
JSON.parse函数本身有可能在您的代码中的其他地方被覆盖(可怕的想法!)。要获得更多信息,您可以尝试使用 reviver 函数来检查JSON.parse正在做什么,如下所示:JSON.parse(mapDataRaw, function(k, v) { console.log(k, v); return v; }); -
哇,Chris G,好主意,结果非常奇怪。以下是它吐出的内容:
{"location":{"row":1,"col":0,"rotate":180,"transform":"rotate(180deg)"},"hp":50,"speed":4,"range":6,"ammo":0,"shieldHP":0,"size":50,"border":"","team":"blue","moved":false,"imgAlpha":"1","unitName":"Fighter","missile":{"firing":true,"target":{"row":2,"col":0}},"img":"assets/img/playerShip1_blue.png","imgTop":{"img":"assets/img/Power-ups/pill_yellow.png","alpha":1,"transform":"","size":22}}所以当你重新字符串化它时,它在解析后仍然得到了正确的数据...... wtf 正在发生吗? -
就像我说的,浏览器的控制台是实时的。见这里:jsfiddle.net/khrismuc/5yjaL9x3
标签: javascript json angular class sockets