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 forEach
método en JavaScript? Lo he return;
intentado return false;
y break
. break
falla y return
no hace nada más que continuar la iteración.
No hay ninguna capacidad incorporada para break
ingresar forEach
. Para interrumpir la ejecución tendrías que lanzar una excepción de algún tipo. p.ej.
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 de JavaScript no son muy bonitas. Un for
bucle tradicional podría ser más apropiado si realmente necesitas break
entrar en él.
UsarArray#some
En su lugar, utilice Array#some
:
[1, 2, 3].some(function(el) {
console.log(el);
return el === 2;
});
Esto funciona porque some
regresa true
tan pronto como cualquiera de las devoluciones de llamada, ejecutadas en orden de matriz, regresa true
, provocando un cortocircuito en la ejecución del resto.
some
, es inverso every
(que se detendrá en a return false
), y forEach
son todos métodos de ECMAScript Quinta Edición que deberán agregarse a los Array.prototype
navegadores donde faltan.
UsarArray#every
[1, 2, 3].every(v => {
if (v > 2) {
return false // "break"
}
console.log(v);
return true // must return true if doesn't break
});
Ahora existe una manera aún mejor de hacer esto en ECMAScript2015 (también conocido como ES6) usando el nuevo for of loop . Por ejemplo, este código no imprime los elementos de la matriz después del número 5:
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (const el of arr) {
console.log(el);
if (el === 5) {
break;
}
}
De los documentos:
Tanto las declaraciones for...in como for...of se repiten sobre algo. La principal diferencia entre ellos está en lo que iteran. La declaración for...in itera sobre las propiedades enumerables de un objeto, en el orden de inserción original. La declaración for...of itera sobre los datos que el objeto iterable define para iterar.
¿Necesita el índice en la iteración? Puedes usar Array.entries()
:
for (const [index, el] of arr.entries()) {
if ( index === 5 ) break;
}
Puedes utilizar todos los métodos:
[1,2,3].every(function(el) {
return !(el === 1);
});
ES6
[1,2,3].every( el => el !== 1 )
para uso de soporte de navegador antiguo:
if (!Array.prototype.every)
{
Array.prototype.every = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this &&
!fun.call(thisp, this[i], i, this))
return false;
}
return true;
};
}
más detalles aquí .
Citando la documentación de MDN deArray.prototype.forEach()
:
No hay otra forma de detener o romper un
forEach()
bucle que no sea lanzando una excepción. Si necesita ese comportamiento, el.forEach()
método es la herramienta incorrecta , utilice un bucle simple en su lugar. Si está probando los elementos de la matriz para un predicado y necesita un valor de retorno booleano, puede usarevery()
osome()
en su lugar.
Para su código (en la pregunta), como lo sugiere @bobince, use Array.prototype.some()
en su lugar. Se adapta muy bien a su caso de uso.
Array.prototype.some()
ejecuta la función de devolución de llamada una vez para cada elemento presente en la matriz hasta que encuentra uno donde la devolución de llamada devuelve un valor verdadero (un valor que se vuelve verdadero cuando se convierte en aBoolean
). Si se encuentra dicho elemento,some()
devuelve verdadero inmediatamente. De lo contrario,some()
devuelve falso. La devolución de llamada se invoca sólo para los índices de la matriz que tienen valores asignados; no se invoca para índices que se han eliminado o a los que nunca se les han asignado valores.
Desafortunadamente, en este caso será mucho mejor si no lo usas forEach
. En su lugar, utilice un bucle normal for
y ahora funcionará exactamente como cabría esperar.
var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
if (array[i] === 1){
break;
}
}
Según su ejemplo de código, parece que Array.prototype.find
es lo que está buscando: Array.prototype.find() y Array.prototype.findIndex()
[1, 2, 3].find(function(el) {
return el === 2;
}); // returns 2