【发布时间】:2018-10-09 15:31:28
【问题描述】:
这里是一个辅助函数,它将一个类似对象的数组转换为一个实际的数组,然后循环遍历可迭代对象,将列表中的每个值提供给回调函数:
var each = function(iterable, callback) {
iterable = Array.prototype.concat.apply([], iterable);
for(var i = 0; i < iterable.length; i++) {
callback.apply(iterable[i], [iterable[i], i]);
}
return iterable;
};
这里我使用前面提到的辅助函数来循环数组:
var found = [];
each(arguments, function(argument) {
each(argument.split(","), function(selector) {
each(handle(selector), function(element) {
if(found.indexOf(element) < 0) {
found.push(element);
}
});
});
});
第一个循环遍历参数。第二个循环拆分选择器,第三个循环遍历请求的元素并将它们添加到 found 数组中(如果它们尚未添加)。
注意:handle 函数采用选择器(一个字符串)并使用document.querySelectorAll 返回一个元素列表。
此脚本有效,但问题在于可读性和性能。
当有许多参数包含多个 (~5-10) 逗号分隔的选择器,然后由 handle 函数单独处理时,就会出现性能问题。
我通过使用类而不是 id 解决了这个问题。
然后是可读性问题,我试图通过将第二个循环移到父循环之外来解决这个问题,但这需要创建更多变量,唯一的区别是改变 where each 循环,这使得可读性更差,因为有更多的代码要阅读。
问题:如何重构代码以减少嵌套循环的数量?
另外,有必要有第一个循环吗?如果我不使用它,我将如何遍历参数以拆分它们以获取每个单独的选择器?我知道split 方法是针对String 类型的,不能在数组上调用。
注意:我使用的是原生 JavaScript,不包括任何库、框架或外部脚本。
【问题讨论】:
-
为什么
handle()只能用“一个”选择器调用(document.querySelectorAll())?为什么each()函数?使用.querySelectorAll(),您已经拥有.forEach(),或者您可以简单地将结果转换为具有.forEach()、.filter()、.reduce()、...的实际数组。 -
恕我直言,这个问题属于codereview.stackexchange.com - 但请检查Help section 在发布之前!
标签: javascript performance refactoring readability