Simple function returning "undefined"

This is the feature I'm working on right now,

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 developed the above function to return the lowest divisor an integer, see the example of case 121 , in fact it should return 11 in the current context. But it returns undefined .


Additional Information:

I checked how many times recursive calls were repeated, it really happened two times, and I only registered the xVal values ​​in two different calls, it just displays 121 and 11 . But I'm really confused here, why is this function currently returning undefined .?

Demo

+6
source share
5 answers
 if (xSqrt % 1 === 0) { return getSmallestDivisor(xSqrt); // missing return here } else { return xVal; } 

Demo: Fiddle

+16
source

Other people gave good, correct answers, but I want to be clear about why , as this may not be obvious to some people (not aimed at the OP).

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

This is called a function call:

 getSmallestDivisor(121) 

At any time, the return keyword is used, the function stops and replaces the function call with what comes after this returned word (this may 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 this function call, which never returns to the original function call that occurred inside alert() .

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

 return getSmallestDivisor(xSqrt); 

This is a common mistake when creating recursive functions. A good way to help understand what is happening is to use the link extensively.

 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 + J on Chrome / Mac) and see what happens - what parts are executed, etc.

+20
source

Just a comment.

Since each if..else block contains a return, the function can be reorganized for use only in the case of 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; } 
+3
source
  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; } 
+1
source
 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 } } } 

I made some changes to your code, now it works.

0
source

All Articles