如何使用ES6的for...of从enermies数组中移除已销毁的Enermy实例?
如何用ES6语法移除数组中已被击杀的敌人?
嘿,这个问题挺常见的!你原来用倒序for循环的写法确实很稳妥,完美避开了数组长度变化导致的索引错乱问题。不过想用ES6的for...of来实现的话,直接在循环里调用splice删除元素会踩坑——因为for...of是基于数组的迭代器工作的,当你修改原数组时,迭代器的指针会混乱,大概率会出现跳过元素或者重复遍历的情况。
下面给你几种更优雅的ES6实现方案:
方案1:用filter创建新数组(最推荐)
如果你的场景允许生成新数组而非修改原数组,filter绝对是最简洁直观的写法,完全符合ES6的风格:
const aliveEnemies = enemies.filter(enemy => !enemy.isKilled);
这种写法可读性拉满,而且是纯函数,不会对原数组产生任何副作用。如果一定要修改原数组的话,直接把结果赋值回去就行:
enemies = enemies.filter(enemy => !enemy.isKilled);
方案2:结合Array.from与迭代器(适合必须修改原数组且想用for...of的场景)
如果你坚持要用for...of循环来操作原数组,可以先把数组的索引和元素转换成可迭代的键值对数组,再倒序遍历(逻辑和你原来的倒序for循环一致,但用了ES6的语法):
for (const [index, enemy] of Array.from(enemies.entries()).reverse()) { if (enemy.isKilled) { enemies.splice(index, 1); } }
这里Array.from(enemies.entries())会把原数组转换成[索引, 元素]格式的新数组,reverse()之后倒序遍历,这样就算删除元素,也不会影响后续要遍历的元素索引,避免了错乱问题。
小提醒:为什么直接用for...of删除会出问题?
举个简单例子:假设数组是[敌A, 敌B, 敌C],其中敌B已被击杀。当你遍历到敌B时删掉它,数组变成[敌A, 敌C],但迭代器的下一个指针已经指向了原来的索引2,而现在数组长度只有2,循环会直接结束,导致敌C根本不会被检查。所以直接在for...of里修改原数组是不可靠的哦。
内容的提问来源于stack exchange,提问作者Yawei Song
相关产品推荐
相关产品推荐

