问题描述

在开发中,实现技能状态的事件监听功能时,将状态对象作为key,存入事件管理器的监听列表,如下图:

实现后,运行程序,并没有报错,但是当某个事件发生时,只有一个状态被触发监听,而大多数状态在创建时,就监听了该事件,正确的表现应当是所有监听该事件的状态对象都被触发。

原因分析

首先判断是状态实现问题,但是每个状态都是继承AbstractState这个父类,并没有重新实现父类的事件监听函数,检查父类监听代码实现,未发现问题。

代码检查没有发现问题,看着是正常的,但实际效果确实有问题,于是添加打印,在addEventListener之前打印监听列表,addEventListener之后也打印监听列表,

打印的结果显示,addEventListener之前如果监听列表为空,那么addEventListener之后会成功添加一个监听,但是如果addEventListener之前监听列表有一个监听了,那么addEventListener之后,监听列表只会剩下最新添加的那个监听!这就是问题所在了,但是为什么会出现这种情况呢?为什么新的对象会覆盖旧的?

将本次遇到的问题简单化成如下例子:

可以看到,b实际上一直只有一个key,即'[object Object]'这个字符串,变化的只是value,在JS中,创建对象时,不论以什么类型的值做Key,JS会默认调用toString()方法将该key转成字符串类型,如数字类型:

可以看到key 1 变成了 '1',而当key时对象时,object.toString()的结果只会等于'[object Object]',如下图:

这就是上面为什么b对象永远只会有一个key =  '[object Object]'的原因,JS不支持对象使用toString()方法,即不支持对象以对象做key。

另外,对象转字符串,JS提供JSON.Stringify()特殊方法。

解决方案

鉴于上面的分析结果,如果还是执意想要用状态对象做key的话,可以使用JSON.Stringify(state),但这显得不够优雅,最后的解决方案是在每个状态对象中,增加一个uuid属性,以该uuid作为Key,存入监听列表中。

 

nodejs以对象做对象的key导致value一直被覆盖的更多相关文章

  1. 对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法

    对象作为 map 的 key 时,需要重写 hashCode 和 equals方法 如果没有重写 hashCode 方法,那么下面的代码示例会输出 null 我们首先定义一个对象:BmapPoint, ...

  2. OC基础--对象做参数在方法间传递

    剧情描述: 美国大兵抗把汉阳造 拿着5个弹夹(每个弹夹5发子弹) 带着弟兄们干架 子弹打完了就求救 类: 士兵: 属性: 姓名(_name) 身高(_height) 体重(_weight) 行为: 开 ...

  3. perl 为什么要用引用来做对象呢?

    perl 为什么要用引用来做对象呢? 因为一个重要的原因是 my 引用 脱离作用域,外部仍旧生效

  4. 打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路3)

    续前一篇:打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路2)ok,到这里已经能够锁定范围了, ...

  5. Thread类线程结束会唤醒使用其对象做锁而睡眠的线程

    首先回顾一下我们的基础知识. sleep: 线程睡眠,不会释放锁 wait: 线程等待.释放锁. notity: 唤醒随机一个当前对象等待的线程,并不会释放锁 notityAll: 唤醒所有当前对象等 ...

  6. 89.[NodeJS] Express 模板传值对象app.locals、res.locals

    转自:https://blog.csdn.net/Elliott_Yoho/article/details/53537437 locals是Express应用中 Application(app)对象和 ...

  7. python基础--面向对象基础(类与对象、对象之间的交互和组合、面向对象的命名空间、面向对象的三大特性等)

    python基础--面向对象 (1)面向过程VS面向对象 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. ...

  8. jquery实现点击展开列表同时隐藏其他列表 js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象

    这篇文章主要介绍了jquery实现点击展开列表同时隐藏其他列表的方法,涉及jquery鼠标事件及节点的遍历与属性操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了jquery实现点击 ...

  9. Json数组对象和对象数组

    Json的简单介绍 从结构上看,所有的数据最终都可以分成三种类型: 第一种类型是scalar(标量),也就是一个单独的string(字符串)或数字(numbers),比如“北京”这个单独的词. 第二种 ...

随机推荐

  1. java web文件上传功能实现

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  2. poj 2559 Largest Rectangle(单调栈)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26549 ...

  3. Jmeter(四)Cookie管理器

    上一节中我们用Jmeter通过接口上传了一张图片到人人网,其中请求头中的Cookie是写死的,这个Cookie其实是登录成功后服务器返回给客户端的,客户端接收到这个Cookie后保存下来,在后续向服务 ...

  4. HTML jQuery 文档操作 - html() 方法

    jQuery 文档操作 - html() 方法 jQuery 文档操作参考手册 实例 设置所有 p 元素的内容: $(".btn1").click(function(){ $(&q ...

  5. sqli-labs(44)

    第四十四关 本关是基于盲注的,这里盲注主要是要没有报错信息,所以要采用盲注.这关与42关的区别就在于没有报错信息 过滤点: $username = mysqli_real_escape_string( ...

  6. 完美解决前端跨域之 easyXDM 的使用和解析

    前端跨域问题在大型网站中是比较常见的问题.本文详细介绍了利用 easyXDM 解决前端跨域的原理细节和使用细节,具体使用时可以在文中代码实例的基础上扩展完成. 0.背景 因个别网络运营商存在 HTTP ...

  7. windows下 java使用zookeeper案例

    依赖: <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeep ...

  8. ValidateUtil常用验证工具类,如手机、密码、邮箱等

    package cn.com.ssk.util.utils; import java.util.regex.Pattern; import org.apache.commons.lang3.Strin ...

  9. python实战,

    1.把日志状态码为200得请求记录下来 记录信息(ip,访问时间,请求资源) 封装函数再次调用,健壮性try except #coding=utf-8import redef  aclog(path, ...

  10. 用了 EventBus 不要多用其他的通讯功能

    EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信.主要功能是替代Intent,Handler,BroadCast