2010-04-05 12 views
74

Me mudé hace un año de los lenguajes OO clásicos, como Java a JavaScript. es, sin duda no se recomienda el siguiente código (o incluso no corrige) en Java:Asignar variable en la declaración de condición de condición, ¿buenas prácticas o no?

if(dayNumber = getClickedDayNumber(dayInfo)) 
{ 
    alert("day number found : " + dayNumber); 
} 
function getClickedDayNumber(dayInfo) 
{ 
    dayNumber = dayInfo.indexOf("fc-day"); 
    if(dayNumber != -1) //substring found 
    { 
     //normally any calendar month consists of "40" days, so this will definitely pick up its day number. 
     return parseInt(dayInfo.substring(dayNumber+6, dayNumber+8)); 
    } 
    else return false; 
} 

Básicamente, sólo descubrí que puedo asignar una variable a un valor en un estado de condición si, y comprobar inmediatamente el valor asignado como si es booleano

Para una apuesta más segura, generalmente lo separo en dos líneas de código, primero asigno y luego verifico la variable, pero ahora que encontré esto, me pregunto si es una buena práctica o no a los ojos de un JavaScript experimentado. desarrolladores?

+0

' "definitivamente no se recomienda el siguiente código (o evento no es correcto) en Java ..."' ¿Es incluso correcta en JavaScript? Porque, hasta donde puedo ver, devuelves un entero ('return parseInt (...)') si 'dayNumber! = -1' es verdadero, pero un boolean si es falso. –

Respuesta

81

No lo recomendaría. El problema es que parece un error común cuando intenta comparar valores, pero usa un solo = en lugar de == o ===. Por ejemplo, cuando vea esto:

if (value = someFunction()) { 
    ... 
} 

usted no sabe si eso es lo que querían hacer, o si se trataba de escribir esto:

if (value == someFunction()) { 
    ... 
} 

Si realmente quiere hacer la asignación en el lugar, yo recomendaría hacer una comparación explícita también:

if ((value = someFunction()) === <whatever truthy value you are expecting>) { 
    ... 
} 
+0

@Matthew Crumley: esto responde mi pregunta de una manera clara. No estoy comprobando asignando pero comprobando lo que el valor evalúa después de la asignación. ¿Es este entendimiento correcto? –

+1

@Michael: sí, eso es correcto. Agregar la comparación básicamente hace que tus intenciones sean más claras. –

+4

El último ejemplo no funciona, sin embargo, si está probando el fracaso/éxito de una función que devuelve un valor booleano. En otras palabras, mientras 'if (resultArr = myNeedle.exec (myHaystack)) {...}' funciona, 'if ((resultArr = myNeedle.exec (myHaystack)) === true) {...}' no porque la asignación a resultArr siempre es cierta incluso cuando el resultado de la función no lo es. Si alguien usa este ... constructo, recuerde declarar primero la variable de resultado; 'var' no es legal dentro de la declaración de condición if. – Ville

5

Puede hacerlo en Java también. Y no, no es una buena práctica. :)

(Y el uso de la === en Javascript por la igualdad escrito leído el libro Buenas piezas de Crockford en JS..)

+0

@quixoto: ¿Podría hacer este truco en Java? Me pregunto ... No tengo jdk a mano, así que no puedo obtener un código de muestra en Java. Desde mi mala memoria, Java solo obtendrá un error de tiempo de ejecución si el valor de retorno evalúa algo no booleano como en el enunciado condicional, ¿verdad? –

+1

Ah, sí, en Java está verificado por tipo para que sea de tipo booleano. Pero usted * puede * hacer 'if (foo = getSomeBoolValue()) {}' –

+0

sí, eso es correcto. una variable booleana para probar si algo tuvo éxito y otra variable para almacenar el valor devuelto. Así es como Java hace su trabajo, estoy muy familiarizado con eso, así que me extraña ver que Javascript puede hacer dos cosas en una sola línea :) –

0

Me parece que es más bien un estilo de la vieja escuela C; en realidad no es una buena práctica en JavaScript, así que debes evitarla.

+7

No considero una buena práctica en C tampoco. –

+0

Lo considero una buena práctica en muchos idiomas. – JDrake

11

Lo hice muchas veces. Para pasar por alto la advertencia de JavaScript, añado dos parens:

if ((result = get_something())) { } 

Debe evitar que, si realmente desea utilizarlo, escribir un comentario sobre ella diciendo lo que está haciendo.

+0

@SHiNKiROU: ¿cómo puedo ver las advertencias de JavaScript? ¿Hay un compilador de Javascript? o el intérprete generará algún tipo de advertencia? Estoy usando la consola de Firefox como en la depuración de JavaScript todo el tiempo, pero nunca veo salidas similares. Lo siento por mi experiencia limitada. –

+4

@Michael: JSLint (http://www.jslint.com/) es un programa/biblioteca popular que comprueba los programas de JavaScript en busca de posibles errores o códigos incorrectos. –

+0

Utilice Mozilla Firefox con Firebug y/o extensión de desarrollador web para verificar las advertencias. –

1

No es una buena práctica. Pronto te confundirás al respecto. Se parece a un error común: uso indebido de operadores "=" y "==".

Debe dividirlo en 2 líneas de códigos. No solo ayuda a que el código sea más claro, sino que también es fácil de refactorizar en el futuro. ¿Imagine que cambia la condición IF? Puede eliminar accidentalmente la línea y su variable ya no obtendrá el valor asignado.

+0

@thethanghn: eso es exactamente a lo que le tengo miedo. Cuando sea mayor y flojo, simplemente no quiero escribir más en el código si bastarán menos teclas :) –

+0

No, no me confundo y lo hago todo el tiempo Hay beneficios para esto. – JDrake

3

También puede realizar asignaciones en sentencias if en Java. Un buen ejemplo podría ser la lectura y la escritura algo en usted mismo:

http://www.exampledepot.com/egs/java.io/CopyFile.html?l=new

El código:

// Copies src file to dst file. 
// If the dst file does not exist, it is created 
void copy(File src, File dst) throws IOException 
{ 
    InputStream in = new FileInputStream(src); 
    OutputStream out = new FileOutputStream(dst); 

    // Transfer bytes from in to out 
    byte[] buf = new byte[1024]; 
    int len; 
    while ((len = in.read(buf)) > 0) { 
     out.write(buf, 0, len); 
    } 
    in.close(); 
    out.close(); 
} 
+0

@Nitrodist: gracias por este ejemplo. Realmente no soy profesional ni en Java ni en JavaScript ... Es bueno saber que este enfoque también es posible en Java :) –

+0

No veo el sentido de esto. Puedes hacerlo en Java, PHP y muchos otros idiomas. La pregunta era sobre Javascript. – pmrotule

+0

No, no es necesariamente, necesita volver a leer la pregunta con cuidado. – Nitrodist

9

no veo ninguna prueba de que no es una buena práctica. Sí, puede parecer un error, pero eso se remedia fácilmente mediante comentarios juiciosos.Tomemos, por ejemplo:

if (x = processorIntensiveFunction()) { // declaration inside if intended 
    alert(x); 
} 

¿Por qué se debe permitir que la función para ejecutar una segunda vez con:

alert(processorIntensiveFunction()); 

Debido a que la primera versión se ve mal? No puedo estar de acuerdo con esa lógica.

+14

No desenterrar un comentario anterior, pero no estoy de acuerdo con tus argumentos. El código legible debe explicarse sin la necesidad de un comentario; agregar un comentario al código confuso no es un remedio. En cuanto a la segunda parte, que dice que la alternativa es volver a llamar a la función, no creo que nadie tenga la intención de hacer eso.En cambio, harías 'x = processItensiveFunction(); if (x) {alerta (x); } ' – maksim

+3

@maksim: Me gusta el código legible, pero eso no significa necesariamente que el código deba ser embrollado o demasiado detallado. Difundir cosas en múltiples líneas y hacer malabares con los valores entre las variables en realidad puede llevar a un código peor. El código insertado puede tener efectos secundarios imprevistos en un lenguaje débilmente tipeado/flexible como JS. La asignación en un enunciado condicional es válida en javascript, porque su solo pregunta "si la asignación es válida, haga algo que posiblemente incluya el resultado de la tarea". Pero, de hecho, asignar antes del condicional también es válido, no demasiado detallado, y más comúnmente utilizado. – Fx32

+0

@maksim ¿por qué piensas que 'if (! X = anyFunction())' no es legible? No necesita ningún comentario de ningún tipo. – JDrake

1

¡Si tuviera que consultar el libro de Martin Fowlers Refactoring improving the design of existing code! Luego hay varios casos en que sería una buena práctica, por ejemplo. condicionales complejas largos para utilizar una llamada de función o método para hacer valer su caso:

"Motivation

One of the most common areas of complexity in a program lies in complex conditional logic. As you write code to test conditions and to do various things depending on various conditions, you quickly end up with a pretty long method. Length of a method is in itself a factor that makes it harder to read, but conditions increase the difficulty. The problem usually lies in the fact that the code, both in the condition checks and in the actions, tells you what happens but can easily obscure why it happens.

As with any large block of code, you can make your intention clearer by decomposing it and replacing chunks of code with a method call named after the intention of that block of code. > With conditions you can receive further benefit by doing this for the conditional part and each of the alternatives. This way you highlight the condition and make it clearly what you > are branching on. You also highlight the reason for the branching."

Y sí su respuesta también es válido para las implementaciones de Java. Sin embargo, no asigna la función condicional a una variable en los ejemplos.

4

Hay un caso cuando lo haces, con while bucles.
Al leer archivos, usualy hace así:

void readFile(String pathToFile) { 
    // Create a FileInputStream object 
    FileInputStream fileIn = null; 
    try { 
     // Create the FileInputStream 
     fileIn = new FileInputStream(pathToFile); 
     // Create a variable to store the current line's text in 
     String currentLine; 
     // While the file has lines left, read the next line, 
     // store it in the variable and do whatever is in the loop 
     while((currentLine = in.readLine()) != null) { 
      // Print out the current line in the console 
      // (you can do whatever you want with the line. this is just an example) 
      System.out.println(currentLine); 
     } 
    } catch(IOException e) { 
     // Handle exception 
    } finally { 
     try { 
      // Close the FileInputStream 
      fileIn.close(); 
     } catch(IOException e) { 
      // Handle exception 
     } 
    } 
} 

Mira el -loop while en la línea 9. Allí, una nueva línea se lee y se almacena en una variable y, a continuación, el contenido del bucle es corrió. Sé que esta no es una declaración if, pero supongo que también se puede incluir un ciclo while en su pregunta.

La razón para esto es que cuando se utiliza un FileInputStream, cada vez que llame FileInputStream.readLine(), se lee la siguiente línea en el archivo, por lo que si lo hubiera llamado desde el bucle con sólo fileIn.readLine() != null sin asignar la variable, en lugar de llamando al (currentLine = fileIn.readLine()) != null, y luego lo llamó desde el interior del bucle también, solo obtendría cada segunda línea.

Espero que lo entiendas, y buena suerte!

0

se podría hacer algo así:

if (value = /* sic */ some_function()){ 
    use_value(value) 
} 
Cuestiones relacionadas