J
Jorge
Is it possible ?
Jorge said:Is it possible ?
Does break; not work ?
Is it possible ?
`throw` will take you out of it. But then you might want a wrapper to
handle it gracefully, and it all adds complexity of course.
Here's an untested example:
Array.prototype.each = (function(){
var stopIterationError = { };
return function(callback, thisValue) {
try {
this.forEach(function() {
if (callback.apply(thisValue, arguments) === false) {
throw stopIterationError;
}
});
}
catch(err) {
if (err !== stopIterationError) {
throw err;
}
}
};
})();
[1,2,3].each(function(item, index){
console.log(arguments);
if (index == 1) return false;
});
(Maybe you can replace that `stopIterationError` object with an object
that inherits from `Error`; I'm not sure how cross-browser it would be)
Is it possible [to break out of a forEach()]?
`throw` will take you out of it. But then you might want
a wrapper to handle it gracefully, and it all adds
complexity of course.
Here's an untested example:
Array.prototype.each = (function(){
var stopIterationError = { };
return function(callback, thisValue) {
try {
this.forEach(function() {
if (callback.apply(thisValue, arguments) === false) {
throw stopIterationError;
}
});
}
catch(err) {
if (err !== stopIterationError) {
throw err;
}
}
};
})();
[1,2,3].each(function(item, index){
console.log(arguments);
if (index == 1) return false;
});
Is it possible ?
AFAIK, it isn't. With iterators, you could at least throw a
StopIteration, but I don't see any possibility with forEach().
You could try using something along the lines of:
function walk (list, fun, context) {
var i = 0,
len = list.length,
rv;
for (; i < len; i++) {
if (i in list) {
rv = fun.call(context, list, i);
if (rv !== undefined) {
return rv;
}
}
}
}
This works similar to Array.prototype.forEach, but will stop looping if
the function "fun" returns anything other than undefined. It can also
double as a filter to find the first array element matching your
criteria. Adding this to Array.prototype is straight-forward, but if
it's stand-alone, you can use it to iterate over node lists (for
example) as well as arrays.
[...]
Great. I wanted to break out from a catch. So I just need to put the
try wrapping the forEach, right ?
e.g.
var n=0;
try {
[1,2,3].forEach(function (value, index, object){
n++;
throw({});
});} catch (e) {
console.log("Broke out @#"+ n);
}
On 3/4/10 11:00 AM, Antony Scriven wrote:
[...]
var LIB = (function(){
Array.prototype.each = function(func, thisvalue){
try{
this.forEach(func, thisvalue);
}catch(e){
if(e !== LIB.stopEach){
throw e;
}
}
};
return {stopEach: {}};
}());
[...]
[...]
<digression>
In a retrospect, this whole idea of throwing wasn't that
good. In most common scenario, breaking out of the loop
was actually _not_ worth performance hit introduced by
try/catch. And since `each` was used everywhere
throughout the library (even in places where plain
`while` would suffice), it's easy to imagine how it all
hindered performance.
</digression>
`return false` idiom probably originates from intrinsic
event handlers, where it would prevent event's default
action. IIRC, jQuery uses it in its own `each`
implementation. `return false` could also be easier to
use, as you don't need to remember the name of error
object.
Is it possible ?
I don't believe there is a reason to. Alter your code.
myArray.filter(...).forEach(...);
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.