Siempre me han enseñado que tener efectos secundarios en una ifafección es malo. Lo que quiero decir es;
if (conditionThenHandle()) {
// do effectively nothing
}
... Opuesto a;
if (condition()) {
handle();
}
... y entiendo eso, y mis colegas están contentos porque no lo hago, y todos nos vamos a casa a las 17:00 un viernes y todos tienen un feliz fin de semana.
Ahora, ECMAScript5 introdujo métodos como every()y some()to Array, y los encuentro muy útiles. Son más limpios que for (;;;)los demás, le dan otro alcance y hacen que el elemento sea accesible mediante una variable.
Sin embargo, al validar la entrada, casi siempre me encuentro usando every/ someen la condición para validar la entrada, luego uso every/ some nuevamente en el cuerpo para convertir la entrada en un modelo utilizable;
if (input.every(function (that) {
return typeof that === "number";
})) {
input.every(function (that) {
// Model.findById(that); etc
}
} else {
return;
}
... cuando lo que quiero hacer es;
if (!input.every(function (that) {
var res = typeof that === "number";
if (res) {
// Model.findById(that); etc.
}
return res;
})) {
return;
}
... lo que me da efectos secundarios en una ifcondición que es mala.
En comparación, este es el código con un viejo for (;;;);
for (var i=0;i<input.length;i++) {
var curr = input[i];
if (typeof curr === "number") {
return;
}
// Model.findById(curr); etc.
}
Mis preguntas son:
- ¿Es definitivamente una mala práctica?
- ¿Estoy (mis | ab) usando
someyevery(¿ debería estar usando afor(;;;)para esto?) - ¿Hay un mejor enfoque?
fuente

some, quiero hacer algo con el elemento, si lo usoevery, quiero hacer algo a todos esos elementos ...someyeveryno me dejen acceder a esa información, así que tampoco puedo los uso, o tengo que agregar efectos secundarios.someen miifcondición para determinar si un determinado elemento de la matriz exhibe una cierta propiedad, 9/10 necesito para operar en ese elemento en miifcuerpo; ahora, comosomeno me dice cuál de los elementos exhibió la propiedad (solo "uno lo hizo"), puedo usarlosomenuevamente en el cuerpo (O (2n)), o simplemente puedo realizar la operación dentro de la condición if ( lo cual es malo, porque es un efecto secundario dentro de la cabeza).everytambién, por supuesto.Respuestas:
Si entiendo su punto correctamente, usted parece ser mis-consumo o abuso
everyysomepero es un poco inevitable si desea cambiar los elementos de las matrices directamente. Corrígeme si me equivoco, pero lo que intentas hacer es averiguar si alguno o todos los elementos de tu secuencia exhiben una determinada condición y luego modificar esos elementos. Además, su código parece estar aplicando algo a todos los elementos hasta que encuentre uno que no pase el predicado y no creo que sea lo que quiera hacer. De todos modosTomemos su primer ejemplo (ligeramente modificado)
Lo que estás haciendo aquí en realidad va un poco en contra del espíritu de algunos / todos / mapas / reducir / filtrar / etc.conceptos.
Everyno debe usarse para afectar a todos los elementos que se ajustan a algo, sino que solo debe usarse para decirle si cada elemento de una colección lo hace. Si desea aplicar una función a todos los elementos para los que un predicado se evalúa como verdadero, la forma "buena" de hacerlo esAlternativamente, puede usar en
foreachlugar de mapa para modificar los elementos en el lugar.La misma lógica se aplica
somebásicamente a:everypara probar si todos los elementos de una matriz pasan alguna prueba.somepara probar si al menos un elemento de una matriz pasa alguna prueba.mappara devolver una nueva matriz que contiene 1 elemento (que es el resultado de una función de su elección) para cada elemento en una matriz de entrada.filterpara devolver una matriz de longitud 0 <length<initial array lengthelementos, todos contenidos en la matriz original y todo pasar la prueba predicado suministrado.foreachsi quieres un mapa pero en el lugarreducesi desea combinar los resultados de una matriz en un solo resultado de objeto (que podría ser una matriz pero no tiene que ser así).Cuanto más los use (y más escriba el código LISP), más se dará cuenta de cómo están relacionados e incluso es posible emular / implementar uno con los demás. Lo que es poderoso con estas consultas y lo que es realmente interesante es su semántica y cómo realmente lo empujan a eliminar los efectos secundarios dañinos en su código.
EDITAR (a la luz de los comentarios): Entonces, supongamos que desea validar que cada elemento es un objeto y convertirlos en un Modelo de aplicación si todos son válidos. Una forma de hacer esto en una sola pasada sería:
De esta manera, cuando un objeto no pasa la validación, aún sigue iterando a través de toda la matriz, lo que sería más lento que simplemente validar con
every. Sin embargo, la mayoría de las veces su matriz será válida (o eso espero), por lo que en la mayoría de los casos realizará una sola pasada sobre su matriz y terminará con una matriz utilizable de objetos del Modelo de aplicación. Se respetará la semántica, se evitarán los efectos secundarios y todos estarán felices.Tenga en cuenta que también podría escribir su propia consulta, similar a foreach, que aplicaría una función a todos los miembros de una matriz y devolverá verdadero / falso si todos pasan una prueba de predicado. Algo como:
Aunque eso modificaría la matriz en su lugar.
Espero que esto ayude, fue muy divertido escribir. ¡Salud!
fuente
if (input.every()), para verificar que cada elemento sea un objeto (typeof el === "object && el !== null), etc., luego , si eso valida, quiero convertir cada elemento en el respectivo modelo de aplicación (que, ahora mencionasmap(), podría usarinput.map(function (el) { return new Model(el); });; pero no necesariamente en su lugar .)map()tener que iterar sobre la matriz dos veces; una para validar y otra para convertir. Sin embargo, utilizando un estándar defor(;;;)bucle, que podía hacer esto utilizando una iteración, pero no puedo encontrar una manera de aplicarevery,some,mapofilter, en este escenario, y realizar sólo un paso, sin tener-secundarios indeseados efectos o la introducción de otro modo mal- práctica.Los efectos secundarios no están en la condición if, están en el cuerpo del if. Solo ha determinado si ejecutar o no ese cuerpo en la condición real. No hay nada malo con su enfoque aquí.
fuente
ifcondición, con solo elreturnser dentro delifcuerpo; obviamente estoy hablando de la muestra de código precedida por " lo que quiero hacer es ...ifcondición.