问题描述

在开发中,实现技能状态的事件监听功能时,将状态对象作为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. NOIP2017提高A组模拟10.6】Biology

    题目 trie 暴力就是对于每个询问的T个字符串 第i个和第i+1个直接个从后暴力枚举每位是否相同, 但这个方法TLE 我们考虑是否可以用更快的方法来求出两个字符串的最长公共后缀. 我们把所有的字符串 ...

  2. 【leetcode】1232. Check If It Is a Straight Line

    题目如下: You are given an array coordinates, coordinates[i] = [x, y], where [x, y] represents the coord ...

  3. Python 模块 Ⅱ

    搜索路径 当你导入一个模块,Python 解析器对模块位置的搜索顺序是: 1.当前目录 2.如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录. 3.如果都 ...

  4. 17.hashlib加密

    import hashlib # 摘要算法(加密算法) # md5 密码加密(保存密文)(输入正确的密码,同一个字符串加密之后密文相同) obj = hashlib.md5("sb" ...

  5. jquery target属性 语法

    jquery target属性 语法 作用:target 属性规定哪个 DOM 元素触发了该事件.大理石平台精度等级 语法:event.targe 参数: 参数 描述 event     必需.规定需 ...

  6. poj 2761 主席树的应用(查询区间第k小值)

    Feed the dogs Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 22084   Accepted: 7033 De ...

  7. Spring Boot教程(三十二)多数据源配置与使用(2)

    Spring-data-jpa支持 对于数据源的配置可以沿用上例中DataSourceConfig的实现. 新增对第一数据源的JPA配置,注意两处注释的地方,用于指定数据源对应的Entity实体和Re ...

  8. Unity3D_(游戏)卡牌01_启动屏界面

      卡牌2D游戏展示 (游戏代码放到  卡牌04_游戏界面  文章最后面~) 游戏项目已托管到github上(里面有个32bit可执行文件) 传送门 规则 开始游戏每张卡牌初始翻开展示 展示几秒后卡牌 ...

  9. mysql 将时间戳与日期时间的转换

    from_unixtime()是MySQL里的时间函数 mysql>SELECT FROM_UNIXTIME( 1249488000, '%Y%m%d' )  ->20071120 mys ...

  10. js中filter过滤用法总结

    定义和用法 filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素. 注意: filter() 不会对空数组进行检测. 注意: filter() 不会改变原始数组 ...