这是我目前正在进行的工作:
function getSmallestDivisor(xVal) {
if (xVal % 2 === 0) {
return 2;
} else if (xVal % 3 === 0) {
return 3;
} else {
var xSqrt = Math.sqrt(xVal);
if (xSqrt % 1 === 0) {
getSmallestDivisor(xSqrt);
} else {
return xVal;
}
}
}
alert(getSmallestDivisor(121));
我设计了上面的函数来返回整数的最小除数。考虑案例121
。它实际上应该在当前上下文中返回11
。但它正在返回undefined
。
我已经检查过递归调用的次数;他们实际上发生了两次。我在这两个不同的调用中记录了xVal
的值,并显示121
和11
。我真的很困惑,为什么这个函数当前正在返回undefined
。
我创建了a jsfiddle demo。
答案 0 :(得分:23)
其他人给出了正确的答案,但我想明确为什么,因为对某些人来说可能并不明显(不是针对OP)。
一个功能只不过是计算机采取的一系列步骤。
这称为函数调用:
getSmallestDivisor(121)
无论何时使用return
关键字,函数都会停止,将函数调用替换为返回单词之后的任何内容(可能没有任何内容)。
所以在这种情况下,原始函数的问题是当脚本到达这一行时......
getSmallestDivisor(xSqrt);
...它返回11 那个函数调用,它永远不会返回到alert()
内发生的原始函数调用。
因此,解决方案只是在它自己调用的地方之前添加return
。
return getSmallestDivisor(xSqrt);
这是制作递归函数时常见的错误。帮助弄清楚发生了什么的好方法是广泛使用browser console。
function getSmallestDivisor(xVal) {
console.log("This is xVal: " + xVal);
if (xVal % 2 === 0) {
console.log("xVal % 2 === 0 was true");
return 2;
}
else if (xVal % 3 === 0) {
console.log("xVal % 3 === 0 was true");
return 3;
}
else {
console.log("This is else.");
var xSqrt = Math.sqrt(xVal);
console.log("This is xSqrt of xVal: " + xSqrt);
if (xSqrt % 1 === 0) {
console.log("xSqrt % 1 === 0 was true... recursing with xSqrt!!!");
getSmallestDivisor(xSqrt);
}
else {
console.log("This is the else inside of else. I am returning: " + xVal);
return xVal;
}
}
}
var y = getSmallestDivisor(121);
console.log("This is y: " + y);
现在在您的浏览器中,您可以open the console(Chrome / Mac上的Option + Command + J)并观察正在发生的事情 - 执行哪些部分等等。
答案 1 :(得分:20)
if (xSqrt % 1 === 0) {
return getSmallestDivisor(xSqrt); // missing return here
} else {
return xVal;
}
演示:Fiddle
答案 2 :(得分:3)
由于每个if..else块都包含一个返回,因此该函数可以重构为仅使用块:
function getSmallestDivisor(xVal) {
if (!(xVal % 2)) return 2;
if (!(xVal % 3)) return 3;
var xSqrt = Math.sqrt(xVal);
if (!(xSqrt % 1)) return getSmallestDivisor(xSqrt);
return xVal;
}
或
function getSmallestDivisor(v, x) {
x = Math.sqrt(v);
return !(v % 2)? 2 : !(v % 3)? 3 : !(x % 1)? getSmallestDivisor(x) : v;
}
答案 3 :(得分:1)
if (xSqrt % 1 === 0) {
// Because if your function walks this way
// it does not meet any 'return' statement
// till the end and returns nothing.
getSmallestDivisor(xSqrt);
} else {
return xVal;
}
答案 4 :(得分:0)
function getSmallestDivisor(xVal) {
if (xVal % 2 === 0) {
return 2;
} else if (xVal % 3 === 0) {
return 3;
} else {
var xSqrt = Math.sqrt(xVal);
alert("xSqrt--"+ xSqrt);
if (xSqrt % 1 == 0) {
return xSqrt;//line changed with else condition ,return xSqrt
} else {
getSmallestDivisor(xSqrt);//line changed with if condition
}
}
}
我已对您的代码进行了一些更改,现在正在运行。
答案 5 :(得分:0)
我真的不能拒绝写这个……因为您的问题和所有答案对我有很大帮助。我遇到了完全相同的问题,我编写了递归函数,并省略了return关键字。此页面节省了我凝视编辑器的时间。
任务:
数字根是数字中所有数字的递归和。 给定n,取n的数字之和。如果该值超过一位,请继续以这种方式减少直到产生一位数字。
function digital_root(n) {
if(n < 10) {
return n;
}
let toString = String(n);
let splitted = toString.split('');
let summArrayItems = function (arr) {
let total = 0;
for(let i = 0; i < arr.length; i++) {
total += Number(arr[i]);
}
return total;
}
let output = summArrayItems(splitted);
if(output < 10) {
return output;
} else {
return digital_root(output); // In this line I omitted return keyword, and received undefined
}
}