La Confusa Coma en JavaScript


No todas las comas en JavaScript son operador, de hecho la mayoría de ellas no lo son. Es hora de afrontar el problema de la confusa coma en JavaScript.

El operador coma en JavaScript es realmente muy simple y, para ser sinceros, nunca es necesario usarla. Lo que es mas probable es que no deberías usarla, pero de todas maneras es importante entenderla.

La Coma Básica


El operador coma entra en la lista de operadores que pueden ser útiles, pero tiene la tendencia a ser usado en maneras que confunden en vez de esclarecer. Parte de la razón para esto es que las comas tienen otros significados en JavaScript.

expresion izquierda, expresion derecha

donde expresion es algo que involucra otros operadores, variables y funciones.

¿Qué Hace el Operador Coma?


Evalúa cada una de las expresiones, empezando por la expresión de la izquierda, y devuelve el valor de la expresión de la izquierda. Por ejemplo:

softwero = (1, 2);

almacena 2 en la variable softwero. Por supuesto, 1 y 2 representan cualquier expresión complicada que puedas imaginarte, y puedes usar expresiones del tipo string, funciones y demás.

Pero, ¿Porqué los Paréntesis?


Esto se debe a que el operador coma tiene la menor prioridad de los operadores en JavaScript, y sin los paréntesis sería ejecutado como:

(softwero = 1), 2;

que resultaría almacenando 1 en la variable softwero y desechando el resultado de la expresión de la derecha.

Si usas mas de una coma, entonces, por las reglas de precedencia de operadores y la asociatividad por la derecha, el resultado es que cada expresión es evaluada de izquierda a derecha, y la última es retornada como resultado. Esto es:

(exp1, exp2, exp3, y así hasta expN)

evaluaría exp1, exp2, etc, y retornaría expN como resultado.

Efectos Secundarios


Para expresiones usando el operador coma como:

softwero = (1, 2);

el valor de la expresión de la izquierda siempre se perdería, así que ¿porqué molestarse? La respuesta es que algunos operadores tienen efectos secundarios, y la mayoría de funciones tienen efectos secundarios. Por ejemplo, puedes usar:

softwero = (console.log(1),console.log(2),console.log(3),4);

y verías 1, 2 y 3 impresos en consola, y softwero tomaría el valor de 4. Por supuesto, dado que las llamadas a funciones y las asignaciones son también sentencias, podemos usar el punto y coma:

console.log(1);console.log(2);console.log(3);softwero=4;

El punto es que los puntos y comas separan sentencias, y las comas separan expresiones, y en algunos casos, también son expresiones. Hay lugares donde solo puedes usar comas, pero a menudo tienes alguna otra opción.

El problema aquí es que algunos programadores usan la coma solo porque se ve cool y lo único que logran es hacerlo todo mas confuso.

 

 Esta No Es La Coma que Estas Buscando


Una razón para la confusión es que hay muchos otros lugares en los que las comas son solo separadores. Por ejemplo, al definir objetos:

var obj = {a:0, b:1, c:function(){}};

las comas son solo separadores. En los arrays:

var arr = [1, 2, 3, 4];

las comas son, también, solo separadores. Quizás el caso mas confuso de todos es en la declaración var. Por ejemplo, en:

var a=1, b=2, c=3;

las comas son solo separadores, y no operadores coma. La razón es que la sentencia var es una declaración e inicialización equivalente a:

var a;
var b;
var c;
a=1;
b=2;
c=3;

Cosas como a=1 son expresiones, el valor de la expresión es, en este caso, 1. Esto permite que puedas escribir cosas como:

a=b=1;

que es equivalente a:

a=(b=1);

Sin embargo,

var a=1;

no es una expresión y no tiene un valor. Mas bien, contiene una expresión porque la inicialización es de la forma:

var variable=expresion;

o también:

var var1=exp1,var2=exp2 y así...

Esto es sutil, pero si agregamos solamente un par de paréntesis, podemos convertir nuestro anterior ejemplo en algo que usa el operador coma:

var a=(1,b=2,c=3);

¿Qué crees que se guarda en a, b y c? La respuesta es que a es 3, b es 2 y c es 3. La sentencia es de la forma:

var a=expresion;

y la expresión es:

(1,b=2,c=3)

que, por las reglas del operador coma, evalúa cada sub-expresión cada vez, desechando cada resultado excepto por el último, que es el valor de la expresión. Cabe destacar que b=2 y c=3 son expresiones, y si b y c no existen, son creadas como variables globales.

Usando La Coma


Ahora que hemos dominado la coma, ¿Para qué podemos usarla? La respuesta honesta es: No para mucho. Hay lugares, especialmente en librerías en los que vas a encontrar el operador coma en uso, pero en la mayoría de los casos hay formas mucho mejores y claras de expresar la misma idea.

La uso mas común del operador coma es hacer bucles mas complejos. En realidad, los bucles for deberían mantenerse simples, así que la idea de hacerlos mas complejos no es buena.

Por ejemplo, ¿de que se trata el siguiente bucle for?

for (var i=0,j=10; i<=j; i++,j--) {
 console.log(i*j);
}

La primera expresión dentro de los paréntesis del bucle no hace uso del operador coma. Solo usa la sentencia var para crear dos variables locales, i y j, y las establece a 0 y 10 respectivamente. La expresión final del bucle es la única que usa el operador coma, y agrega 1 a i y substrae 1 a j cada vez que se ejecuta el bucle. Asi que los valores para i y j creados son:

0 10
1 9
2 8
3 7
4 6
5 5

y termina el bucle. ¡Qué inteligente! ¿No? Se podría haber escrito así:

for (var i=0,j=10; i<=j; i++) {
 console.log(i*j);
 j--;
}

Puedes usar una técnica similar para convertir un bucle while en una especie de bucle for:

var i=0;
while (i++, i<10) {
 console.log(i)
}

Hay bastantes usos similares y ejemplos, pero todas se reducen a lo mismo: Necesitamos usar una sola expresión, pero también necesitamos evaluar otras expresiones primero solo por sus efectos secundarios.

Conclusión


La situación se resume en "Necesitas entender la coma, pero probablemente no necesites usarla". Lo que realmente importa es no confundir los muchos usos de la coma con el operador coma.

Extra

Otro uso que se puede encontrar del operador coma es dentro del operador ternario ?, así:

faltantes ? (faltantes--, intentar()):(noMasFaltantes(), terminar());

En este caso es mucho mas difícil de entender y se podría hacer de una forma muchísimo mas clara, pero este pequeño ejemplo recalca nuestra conclusión.

Y tu, ¿Conoces otro uso del operador coma? Cuéntanos en los comentarios.

No hay comentarios:

Publicar un comentario