簡體   English   中英

返回“未定義”值的簡單函數

[英]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的值,它們顯示12111 我真的很困惑為什么這個函數當前返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM