Reputation: 25
I've done quite a bit of reading and seen many different questions regarding this topic, but I was wondering if I could get help on WHY breaking out of a For Each loop doesn't work. Also, I am pretty new, so I apologize in advance if this question was answered in a different way that I wasn't able to understand.
So far, I have written a forEach function to emulate a native .forEach method:
function forEach(collection, callback){
if(collection.isArray){
for(var i =0;i<collection.length&&callback(collection[i])!==false;i++){
callback(collection[i]);
}
}else{
for(var key in collection){
callback(collection[key]);
}
}
}
When I try to utilize this to write another function 'find' that searches for the first instance of the array that matches a criteria, using 'return' or 'break' doesn't seem to work. find([1,2,3,4,5].function(x){return x>3;}); returns 5 instead of 4.
function find (collection, criteria){
var result;
forEach(collection, function(x){
if(criteria(x)){
result =x;
return false;
}
});
return result;
}
I have been able to recreate the effect that I want using other functions, but would like to understand why this doesn't work, as I am learning how to implement the use of functions within other functions.
Thank you.
Upvotes: 1
Views: 290
Reputation: 18559
For an array, collection.isArray
is undefined
. You should replace this with Array.isArray(collection)
.
For non-array types, you're not checking the return value of callback(collection[key])
.
Upvotes: 0
Reputation: 129149
Consider the behavior of bar
in this code snippet:
function foo(x) {
return x;
}
function bar() {
foo(1);
foo(2);
return 3;
}
console.log(bar());
It calls foo
, which returns, but it is returning control back to bar
itself, not to the caller of bar
, so this logs 3.
The situation does not change if we put the definition of foo
inside bar
:
function bar() {
function foo(x) {
return x;
}
foo(1);
foo(2);
return 3;
}
console.log(bar());
Nor does it change if we accept it as a parameter:
function foo(x) {
return x;
}
function bar(baz) {
baz(1);
baz(2);
return 3;
}
console.log(bar(foo));
The behavior does not change when we use a function expression, either:
function bar(baz) {
baz(1);
baz(2);
return 3;
}
console.log(bar(function(x) {
return x;
}));
So the reason return
does not work the way you are expecting from a function passed to forEach
is that return
retains its usual meaning of returning from the function it is in—not the function that lexically encloses that function. Similarly, break
is illegal because it is not in a loop; it is in a function (that only happens to be called in a loop later on).
Upvotes: 2