为什么版本A有效,但版本B没有?如何在不在函数外声明全局变量的情况下使版本B工作(这是不好的做法)? 我不清楚为什么我不能在函数本身内声明计数。
A)
var count = 0;
var containsFiveOrMoreDivs = function(domElement) {
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
} else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (containsFiveOrMoreDivs(children[i])) {
return true;
}
}
}
return false;
}
};
B)
var containsFiveOrMoreDivs = function(domElement) {
var count = 0;
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
} else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (containsFiveOrMoreDivs(children[i])) {
return true;
}
}
}
return false;
}
};
答案 0 :(得分:7)
你真正需要的是两个功能,一个在另一个内部:
class LoginViewController: UIViewController {
...
...
}
在该设置中,传入元素引用,然后外部函数在初始化计数器后调用内部函数。
原来这里答案不是很好
您的第二个版本(“B”)已“计数”为该函数的局部变量。每次调用函数都会得到它自己的“count”变量,并且在每次调用时,首先发生的事情是它被初始化为零。
如果您不想要全局,可以使用闭包:
function containsFiveOrMoreDivs(domElement) {
var count = 0;
function doCount(domElement) {
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
}
else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (doCount(children[i])) {
return true;
}
}
}
return false;
}
}
return doCount(domElement);
}
该代码将您的实际计数器函数包装在包含“count”变量的匿名函数中。它不会是全球性的;它对“containsFiveOrMoreDivs”函数完全是私有的。这就像两全其美:你将“计数”视为全局,但不全球。您无需担心携带参数。
答案 1 :(得分:3)
Javascript中的变量存在于函数范围内。每次调用containsFiveOrMoreDivs时,在版本B中count都将始终为0.因此,无限递归。
但是,每次从函数中调用时,你可以做的是传递'count',并使用它(确保它第一次正确初始化):
var containsFiveOrMoreDivs = function(domElement, count) {
if (!count) {
count=0;
}
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
} else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (containsFiveOrMoreDivs(children[i], count)) {
return true;
}
}
}
return false;
}
};
就像你现在所说的那样(containsFiveOrMoreDivs('elementname');
)
答案 2 :(得分:2)
版本B不起作用,因为每次调用该函数时,counter
都会重新声明,因此counter
永远不会递增。
答案 3 :(得分:2)
您的递归函数需要将count作为参数。你拥有它的方式无论你递归多少次都会将数字初始化为0。
这是一个递归函数的示例,它使用“执行某些操作的次数”作为参数。修改它以支持您的案例。您的基本情况类似于“count大于5”,每次递归调用时,都会为递归调用提供的计数加1。
var containsFiveOrMoreDivs = function() {
var count = 0;
return function(domElement) {
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
} else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (containsFiveOrMoreDivs(children[i])) {
return true;
}
}
}
return false;
}
};
}();
答案 4 :(得分:2)
您可以使用count
参数定义函数并传递初始值,或者如果您使用的是ECMA 16,则可以通过count=0
为参数设置默认值。
var containsFiveOrMoreDivs = function(domElement, count) {
if (domElement && domElement.tagName === "DIV") {
count++;
}
//base case:
if (count >= 5) {
return true;
} else {
if (domElement.hasChildNodes()) {
var children = domElement.childNodes;
for (var i = 0; i < children.length; i++) {
if (containsFiveOrMoreDivs(children[i]), count) {
return true;
}
}
}
return false;
}
};
// call function and set counter to some initial value, such as zero
containsFiveOrMoreDivs(domElement, 0);