Cortocircuito Array.forEach como llamar a break

[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

¿Cómo puedo hacer esto usando el nuevo método forEach en JavaScript? He probado con return, return false y break. break se bloquea y return no hace nada más que continuar la iteración.

Solución

No hay una capacidad incorporada para break en forEach. Para interrumpir la ejecución tendrías que lanzar una excepción de algún tipo.

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

Las excepciones en JavaScript no son muy bonitas. Un bucle tradicional for podría ser más apropiado si realmente necesitas break dentro de él.

Usa Array#some

En su lugar, utiliza Array#some:

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

Esto funciona porque alguno devuelve true tan pronto como cualquiera de los callbacks, ejecutados en orden de array, devuelven true, cortocircuitando la ejecución del resto.

some, su inverso every (que se detendrá en caso de retorno false), y forEach son todos métodos de la Quinta Edición de ECMAScript que tendrán que ser añadidos a Array.prototype en los navegadores donde falten.

Comentarios (14)

Considera usar el método each de jquery, ya que permite devolver false dentro de la función callback:

$.each(function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Las librerías Lodash también proporcionan el método takeWhile que puede ser encadenado con map/reduce/fold etc:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];

_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']

// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']

// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']

// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
Comentarios (3)

Encontré esta solución en otro sitio. Usted puede envolver el forEach en un escenario try / catch.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

Más detalles aquí: http://dean.edwards.name/weblog/2006/07/enum/

Comentarios (1)