受限JavaScript环境下HashMap键的高效遍历方案咨询
嘿,这个问题问得好!既然你受限不能用2015年后的JavaScript特性,但又想找比手动管理索引的for循环更优雅的遍历方式,我来给你分两种情况梳理:
ES5是2011年发布的,完全在你允许的范围内,这里有两个靠谱的选项:
Array.prototype.forEach(推荐)
如果你的keySet()返回的是数组(或者类数组对象),可以用forEach来遍历,不用手动维护索引,代码更简洁易读。如果是类数组(比如某些自定义集合返回的结果),可以用call来借用数组的forEach方法:// 如果keys是数组 keys.forEach(function(key) { something(key); }); // 如果keys是类数组(比如DOM集合或自定义keySet返回值) Array.prototype.forEach.call(keys, function(key) { something(key); });优点:写法简洁,不用关心索引边界,可读性强;性能和普通for循环相差无几,大多数场景下完全够用。
缺点:无法中途用break终止遍历,如果需要终止的话可能还是得用for循环。for...in(不推荐,除非特殊情况)
如果你一定要用迭代式的写法,for...in也可以,但要注意它会遍历对象原型链上的属性,所以必须加上hasOwnProperty检查来避免意外:for (var i in keys) { if (keys.hasOwnProperty(i)) { something(keys[i]); } }优点:写法比手动for循环少写点代码;
缺点:性能不如forEach和普通for循环,而且容易因为原型链污染出现问题,所以一般不推荐用在数组/类数组的遍历上。
虽然你现在没法用,但这些方案在现代JS里是更优的选择,值得了解:
for...of 遍历迭代器
如果是原生Map(而非自定义HashMap),它的keys()方法返回一个迭代器,直接用for...of遍历最简洁:for (const key of map.keys()) { something(key); }优点:写法直观,支持
break/continue终止或跳过遍历,性能优秀。Map.prototype.forEach
原生Map自带forEach方法,还能同时拿到键和值,如果你需要值的话更方便:map.forEach(function(value, key) { something(key); // 顺便还能用到value,一举两得 });优点:不用先获取keySet,直接操作Map本身,代码更紧凑。
Array.from + 箭头函数
把迭代器转成数组后用箭头函数遍历,写法更简洁:Array.from(map.keys()).forEach(key => something(key));优点:箭头函数语法更简短,适合简单逻辑。
内容的提问来源于stack exchange,提问作者Stefan

