nodejs以对象做对象的key导致value⼀直被覆盖
js获取json的key和value
问题描述
在开发中,实现技能状态的事件监听功能时,将状态对象作为key,存⼊事件管理器的监听列表,如下图:
实现后,运⾏程序,并没有报错,但是当某个事件发⽣时,只有⼀个状态被触发监听,⽽⼤多数状态在创建时,就监听了该事件,正确的表现应当是所有监听该事件的状态对象都被触发。
原因分析
⾸先判断是状态实现问题,但是每个状态都是继承AbstractState这个⽗类,并没有重新实现⽗类的事件监听函数,检查⽗类监听代码实现,未发现问题。
代码检查没有发现问题,看着是正常的,但实际效果确实有问题,于是添加打印,在addEventListener之前打印监听列
表,addEventListener之后也打印监听列表,
打印的结果显⽰,addEventListener之前如果监听列表为空,那么addEventListener之后会成功添加⼀个监听,但是如果addEventListener 之前监听列表有⼀个监听了,那么addEventListener之后,监听列表只会剩下最新添加的那个监听!这就是问题所在了,但是为什么会出现这种情况呢?为什么新的对象会覆盖旧的?
将本次遇到的问题简单化成如下例⼦:
可以看到,b实际上⼀直只有⼀个key,即'[object Object]'这个字符串,变化的只是value,在JS中,创建对象时,不论以什么类型的值做Key,JS会默认调⽤toString()⽅法将该key转成字符串类型,如数字类型:
可以看到key 1 变成了 '1',⽽当key时对象时,String()的结果只会等于'[object Object]',如下图:
这就是上⾯为什么b对象永远只会有⼀个key =  '[object Object]'的原因,JS不⽀持对象使⽤toString()⽅法,即不⽀持对象以对象做key。
另外,对象转字符串,JS提供JSON.Stringify()特殊⽅法。
解决⽅案
鉴于上⾯的分析结果,如果还是执意想要⽤状态对象做key的话,可以使⽤JSON.Stringify(state),但这显得不够优雅,最后的解决⽅案是在每个状态对象中,增加⼀个uuid属性,以该uuid作为Key,存⼊监听列表中。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。