This is the function I am currently working on:
function getSmallestDivisor(xVal) {
if (xVal % 2 === 0) {
return 2;
} else if (xVal % 3
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;
}
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.
I really can't resist to write this...because your question and all of the answers helped me so much. I had the exact same problem, I wrote recursive function and omitted return keyword. This page saved me hours of staring at the editor.
The task:
Digital root is the recursive sum of all the digits in a number. Given n, take the sum of the digits of n. If that value has more than one digit, continue reducing in this way until a single-digit number is produced.
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
}
}
if (xSqrt % 1 === 0) {
return getSmallestDivisor(xSqrt); // missing return here
} else {
return xVal;
}
Demo: Fiddle
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 have made some changes in your code,it's working now.
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;
}