Dan Rubio Dan Rubio - 13 days ago 5
Javascript Question

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.

Answer

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.

Comments