Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple function returning 'undefined' value

This is the function I am currently working on:

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));

I had designed the above function to return the lowest divisor of an integer. Consider the case 121. It should actually return 11 in the current context. But it is returning undefined.

I have checked how many times the recursive calls happened; they actually happened two times. I logged the values of xVal in those two different calls, and they display 121 and 11. I am really confused here about why this function is currently returning undefined.

I've created a jsfiddle demo.

like image 331
Rajaprabhu Aravindasamy Avatar asked Jan 17 '14 05:01

Rajaprabhu Aravindasamy


People also ask

Why is my function returning undefined?

A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .

Why does my array return undefined?

The array the map() method returns consists of the values that are returned from the callback function. If you don't return a value from a function in JavaScript, you implicitly return undefined . Copied! This is the most common reason the map() method returns an array containing undefined values.

Can Boolean return undefined?

The Boolean value of undefined is false. The value of Not only undefined but also null, false, NaN, empty string is also false.

What can a function return?

A return is a value that a function returns to the calling script or function when it completes its task. A return value can be any one of the four variable types: handle, integer, object, or string. The type of value your function returns depends largely on the task it performs.


3 Answers

Other people have given good, correct answers but I want to be explicit about why, since it might not be obvious to some people (not directed at the OP).

A function is nothing more than a set of steps for the computer to take.

This is known as a function call:

getSmallestDivisor(121)

Anytime the return keyword is used, the function stops and replaces the function call with whatever comes after that return word (it could be nothing).

So in this case, the problem with the original function is that when the script reaches this line...

getSmallestDivisor(xSqrt);

...it returns 11 to that function call, which never gets returned to the original function call that happened inside of alert().

So the solution is simply to add a return before the one where it calls itself.

return getSmallestDivisor(xSqrt);

This is a common mistake when making recursive functions. A good way to help figure out what is going on is to make extensive use of the 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);

Now in your browser, you can open the console (Option + Command + I in most browsers on macOS) and watch what is happening - which parts get executed, etc.

like image 195
Seth Holladay Avatar answered Oct 13 '22 08:10

Seth Holladay


if (xSqrt % 1 === 0) {
    return getSmallestDivisor(xSqrt); // missing return here
} else {
    return xVal;
}

Demo: Fiddle

like image 22
Arun P Johny Avatar answered Oct 13 '22 07:10

Arun P Johny


Just a comment.

Since each if..else block contains a return, the function can be refactored to use just if blocks:

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;
}

or

function getSmallestDivisor(v, x) {    
    x = Math.sqrt(v);
    return !(v % 2)? 2 : !(v % 3)? 3 : !(x % 1)? getSmallestDivisor(x) : v;
}
like image 3
RobG Avatar answered Oct 13 '22 07:10

RobG