[英]Simple function returning 'undefined' value
這是我目前正在研究的功能:
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
。
我創建了一個 jsfiddle 演示。
其他人給出了很好的、正確的答案,但我想明確說明原因,因為這對某些人來說可能並不明顯(不是針對 OP)。
函數只不過是計算機要執行的一組步驟。
這稱為函數調用:
getSmallestDivisor(121)
每當使用return
關鍵字時,該函數都會停止並用該返回字之后的任何內容替換函數調用(它可能什么都沒有)。
所以在這種情況下,原來函數的問題是,當腳本到達這一行時......
getSmallestDivisor(xSqrt);
...它向該函數調用返回 11,該函數調用永遠不會返回到發生在alert()
內部的原始函數調用。
所以解決方案只是在它調用自己的那個之前添加一個return
。
return getSmallestDivisor(xSqrt);
這是制作遞歸函數時的常見錯誤。 幫助弄清楚發生了什么的一個好方法是廣泛使用瀏覽器控制台。
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);
現在,在您的瀏覽器中,您可以打開控制台(在 macOS 上的大多數瀏覽器中為Option + Command + I )並觀察正在發生的事情 - 哪些部分被執行等。
if (xSqrt % 1 === 0) {
return getSmallestDivisor(xSqrt); // missing return here
} else {
return xVal;
}
演示:小提琴
由於每個 if..else 塊都包含一個返回值,因此可以重構該函數以僅使用 if 塊:
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;
}
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;
}
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
}
}
}
我對您的代碼進行了一些更改,現在可以使用了。
我真的忍不住要寫這個……因為你的問題和所有的答案都對我有很大幫助。 我遇到了完全相同的問題,我編寫了遞歸函數並省略了 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 } }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.