我试图理解这段代码,它使用递归来检索给定 CSS 类的所有 HTML 元素:
var getElementsByClassName = function(className, element = document.body) {
var arr = [];
if (element.classList && element.classList.contains(className)) {
arr.push(element);
}
for (var i = 0; i < element.childNodes.length; i++) {
var res = getElementsByClassName(className, element.childNodes[i]);
arr = arr.concat(res);
}
return arr;
};
起初我以为我理解了,假设
arr
连接 arr
的内容,并在每次递归调用中使用新元素进行初始化。
但后来我发现我错了。或者,如果我没有错的话,那它是如何工作的呢?
由于
var res
正在进行递归调用,但更重要的是,它的内容要与arr连接?我迷路了...
我们可以去掉
var res
而使用
arr = arr.concat(getElementsByClassName(className, element.childNodes[i]))
整个过程是如何进行的?
您在标题中写道:
...因为
只是递归函数而不是数组res
这似乎是误解的核心。它是数组。如果
res
是“只是递归函数”,那么您需要分配一个函数(对象),但在这里您 call 该函数,然后函数执行,返回一些东西(在本例中是一个数组)并且这就是右侧的计算结果——不是函数,而是其执行返回的结果。
用一个简单的函数来说明:
var x = Math.abs;
这里
x
是一个函数对象。但如果我们调用它...
var x = Math.abs(-3)
...那么
x
就没有abs
这个函数的踪迹了。它只是值 3。
在您的情况下,该函数返回一个数组,其中包含唯一的
return
语句:return arr
。由于 arr
是一个数组,我们可以相信该函数始终返回一个数组。
我们可以去掉
而使用var res
arr = arr.concat(getElementsByClassName(className, element.childNodes[i]))
是的,这实际上具有相同的效果。请注意,在这两种情况下,您都执行函数
getElementsByClassName
并使用它返回的值作为调用 concat
的参数。