问题描述

在开发中,实现技能状态的事件监听功能时,将状态对象作为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. Codeforces Round #395 Div.1 C pacifist【JZOJ5449】Pacifist

    题目 papyrus 喜欢谜题... 来解一道如何? 在你面前有一个被加密了的数组,其原数组是一个等差序列,你面前的则是将原数组中的所有数字都对m 取模再打乱后而得到的新数组 papyrus 给你出的 ...

  2. linux环境下写C++操作mysql(二)

    main.cpp #include<stdio.h> #include<stdlib.h> #include"mysqlInterface.h" int m ...

  3. kill 与 killall和过滤后杀掉

    1.绝杀 kill -9 PID  杀掉单一进程  例如:kill -9 pid号   同意的 kill -s SIGKILL   这个强大和危险的命令迫使进程在运行时突然终止,进程在结束后不能自我清 ...

  4. IDEA 无法自动导入相关Maven jar包

    仔细看看项目右边有个很骚的"Maven Projects"按钮,点击一下 再点击这个刷新按钮,现在知道技术为何物了吗?

  5. 6张图解释IO流

    1.字节流InputStream 2.字节流OutputStream 3.字符流Reader 4.字符流Writer 5.节点流 6.处理流 总结: 节点流可以直接连接在数据源上,处理流不可以:节点流 ...

  6. 选题 Scrum立会报告+燃尽图 04

    本次作业要求参见:edu.cnblogs.com/campus/nenu/2019fall/homework/9913 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名:胜利点 二.S ...

  7. 9、kubernetes之statefulset控制器

    一.StatefulSet 有状态副本集 必要的三个组件:headless service.StatefulSet.volumeClaimTemplate 准备pv apiVersion: v1 ki ...

  8. What is the most efficient way to deep clone an object in JavaScript?

    What is the most efficient way to deep clone an object in JavaScript? Reliable cloning using a libra ...

  9. 第五周作业,LVM和TCP

    1.磁盘lvm管理,完成下面要求,并写出详细过程: 1) 创建一个至少有两个PV组成的大小为20G的名为testvg的VG;要求PE大小 为16MB, 而后在卷组中创建大小为5G的逻辑卷testlv; ...

  10. 【3】火狐中: radio被点击以后,重刷页面,不会选择默认的radio

    1.问题:火狐中radio (单选框)点击以后,重新刷新页面,不会选择默认的radio 解决:form表单中添加:autocomplete="off" autocomplete 属 ...