How does return works in JavaScript - javascript

I have one simple recursive function which adds all it's previous numbers.
function add(n) {
if (n == 0) {
return 1; // when it reaches here it should give me 1.
}
return n + add(n - 1);
}
console.log( add(5) ); // give me 16
when the execution reaches line number 3, it should return me 1, but it is return me 16. how return is actually working here ?

Recursion pauses the program at recursion step call and continue solving the sub problem and when a base condition is hit all the return statements pass the control back to the callee statement.
So
add(5)-->return 5+add(4)
|-->return 4+add(3)
|-->return 3+add(2)
|-->return 2+add(1)
|-->return 1+add(0)//base condition, return 1 for add(0) which in return return 2
1-->2-->4-->7-->11-->16 (In reverse)

that is because the conditional statement that your line 3 is in says to return 1 only if the argument n passed in is equals to 0. The function you are calling at the end of the code is passing in an argument of 5.
the first return statement would only work if condition in the if statement is true, otherwise it goes to the second return which calls the function again within itself.

Related

return statement that returns nothing in recursion

I found this code about recursion online
function countDownRecursive(n) {
if (n <= 0) {
console.log('Hooray')
return
}
console.log(n)
countDownRecursive(n - 1)
}
I am really confused about this code, why does it console.log("Hooray") and then return nothing? Can you explain it to me? Thank you so much.
you returned a null value, the function output type is void.
try this
if (n <= 0) {
console.log('Hooray')
return n
}
return in this context means you don't want to continue running the function (similar to break in iterations).
The above recursive function's logic can be converted to this below while logic.
let n = 3;
//iterate until found the while break
while (true) {
//the condition to stop
if (n <= 0) {
console.log('Hooray');
break; //stop `while`
}
console.log(n)
n = n - 1;
}
why does it console.log("Hooray")
Because the function is recursive and when you start with let's say n=1 the function will not print "Hooray" immediately, because the condition:
if (n <= 0)
does not apply i.e. is false.
By the time we reach the recursion:
countDownRecursive(n - 1)
We call the function again with n=0 due to n - 1, the if-statement will evaluate to true and therefore print "Hooray".
and then return nothing
It does not actually return "nothing", even though the return type is void, it returns undefined, which is the default behavior for return you could also write return undefined instead.
When you use return, it will basically terminate or return from the current function. It will jump back into the scope where you did call the function initially.
Hope that clears it up for you.
Let's do it with an example. This is the hierarchy of the calls when n = 5
countDownRecursive(5) // "5"
countDownRecursive(4) // "4"
countDownRecursive(3) // "3"
countDownRecursive(2) // "2"
countDownRecursive(1) // "1"
countDownRecursive(0) // "Hooray" because n == 0, we execute the return statement
end of countDownRecursive(0) because of return
end of countDownRecursive(1) because reaching the end
end of countDownRecursive(2) because reaching the end
end of countDownRecursive(3) because reaching the end
end of countDownRecursive(4) because reaching the end
end of countDownRecursive(5) because reaching the end
The returns statement tells the program to stop calling itself

Factorial recursion, giving undefined

I am trying to simply find recursion factorial
function factorial(num, result) {
console.log('num', num)
if (num === 0) {
console.log('res ', result);
return result;
} else {
result = result * num;
console.log(result)
factorial(--num, result);
}
}
let res = factorial(3, 1)
console.log(res)
It is giving undefined, not sure why, need some help.
plnkr
Bside the missing return statement, some annotations:
Use a default value for the result. This enables to call the function without given a starting value and allows touse only a single parameter.
Take only one early exit of the recursive call, without using else in combination with return. The return statement omits the following else statement. Just go on with the code without an else part.
Return at the end of the function a recursive call to allow to use the compiler to take a TCO (tail call optimization). This wotks without extending the stack, because the last call is replace with the actual recursive call. This optimization may not actually implemented.
Do not use decrement operators, if you need only the reduced value without using the reduced value again.
Move the calculation into the function call.
function factorial(num, result = 1) {
console.log('num', num);
if (num === 0) return result;
return factorial(num - 1, result * num);
}
console.log(factorial(3))

Confused about the `return` statement in javascript. Explanation needed

I posted a question not too long ago this morning regarding a kata that I was trying to solve. In that question, (found here if interested Kata Question) I needed to add a return statement to my function so that I would avoid the following error Value is not what was expected.
Now I have my second iteration of my kata solution to try out and here it is:
function isMerge(s, part1, part2) {
var pointer = 0
splitString = s.split('');
splitString.forEach(function(character) {
if (part1.includes(character) || part2.includes(character)) {
pointer++;
return true;
} else {
return false;
}
});
}
isMerge('codewars','cdw','oears')
I am still getting Value is not what was expected errors when I try to execute the code and this time I'm confused as to why in particular this happens.
For starters, taken from the MDN guide
The return statement ends function execution and specifies a value to be returned to the function caller.
expression
The expression to return. If omitted, undefined is returned instead.
Look at my if/else logic I am specifying a return true and return false condition in my forEach loop to see if all the chars from part1 and part2 are in the string. I am returning something so why is it that I have a Value is not what was expected?.
Second of all, by definition of the return statement, the function is supposed to stop when it reaches that keyword. However, when I place a console.log(character) in the logic, I can see on my console that all of the characters are being outputted so the function is not breaking at all when return true is executed. Why is that?
Third, I am confused as to when to use the return keyword in general. Consider these examples from the MDN docs for ForEach.
Example 1:
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}
// Notice that index 2 is skipped since there is no item at
// that position in the array.
[2, 5, , 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[3] = 9
Example 2:
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
// ^---- Note
};
var obj = new Counter();
obj.add([2, 5, 9]);
obj.count
// 3
obj.sum
// 16
Not a single return statement to in these examples.
Now look at this .every example.
function isBigEnough(element, index, array) {
return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough);
And finally, from my previous question, I need to add a second return statement like this to avoid the value error.
function isBigEnough(element, index, array) {
return element >= 10;
}
function whenToUseReturn(array) {
return array.every(isBigEnough);
}
whenToUseReturn([12, 5, 8, 130, 44]);
So....... in conclusion, for my original function that started this how am I supposed to exit the loop when I reach false and return it and likewise when all the characters are in the string, how do I return a 'cumulative' true and avoid a Value error. I hope this makes sense and I can clarify with edits to better illustrate my point.
I am returning something so why is it that I have a Value is not what was expected?.
The return statement returns from the callback you pass to forEach, not from isMerge. return statements don't cross function boundaries. isMerge doesn't contain a return statement, hence it returns undefined. If we rewrite the function slightly it might become clearer:
function doSomething(part1, part2) {
return function(character) {
if (part1.includes(character) || part2.includes(character)) {
return true;
} else {
return false;
}
}
}
function isMerge(s, part1, part2) {
splitString = s.split('');
splitString.forEach(doSomething(part1, part2));
}
isMerge('codewars','cdw','oears')
This is equivalent to your code. As you can see, there is no return statement in isMerge.
Not a single return statement to in these examples.
There are no return statements in the forEach examples because forEach doesn't do anything with the return value of the callback, so there is no point in returning anything.
forEach is just a different way to iterate over an array, but it doesn't produce a value like reduce or every.
how am I supposed to exit the loop when I reach false and return it and likewise when all the characters are in the string, how do I return a 'cumulative' true and avoid a Value error.
You cannot exit a forEach "loop". If you have to stop the iteration early, you need to use a normal for (for/in, for/of) loop.
To return and produce a value, you can use your original solution that uses every.
My friend, since you decided to go the "callback way" using .each and the like, you should consider using callbacks, since you cannot return anything in this case. If you do not wish to go the callback way, just use standard javascript, such as:
splitString.forEach(function(character) {
Replace with
for(var i = 0 ; i < splitString.length; i++){
And now you can return. Using "each" to loop an array is just plain unnecessary and prevents you to return.

Writing a recursive JavaScript function returns "undefined"

I am trying to learn recursive functions in JS but for some reason the result is undefined I want to alert (4,3,2,1,0) respectively.
function someFun(number) {
if (number < 0) {
return 1;
}
else {
alert(number = someFun(number - 1))
}
}
someFun(4)
Your function only has one return statement in it. When the else path of the if statement is taken, nothing is returned.
That said, you really don't need a return value because you just want the sequence of numbers printed (in descending order):
function someFun(number) {
if (number >= 0) {
alert(number);
someFun(number - 1);
}
}
someFun(4);
If you want the numbers printed in ascending order, you'd just reverse the order of the alert() and the recursive call.

recursive function return different values depending of order when summing array elements

I implemented the following recursive JS function to get the the sum of elements in a array. This function works fine, when input [1,2,3] it returns 6, which is OK.
function sumOfNumbers(array) {
if (array.length == 1) {
return array[0];
} else {
last = array.length - 1;
return array[last] + sumOfNumbers(array.slice(0, last));
}
}
However, when changing the order of the sum to:
return sumOfNumbers(array.slice(0,last)) + array[last];
It returns 5 for [1,2,3]. Does anybody knows why?
Because the variable last is global, and you're changing it with your call to sumOfNumbers(array.slice(0,last)), before this part: array[last] sees it.

Categories