Wat the JS

Bruno Pineda
sngular-devs
Published in
6 min readAug 29, 2018

La falta de entendimiento es lo que lo hace divertido

Resultado de imagen para watman

Recuerdan aquel vídeo titulado Watman o Wat JS, bueno para aquellos que no lo recuerdan o nunca lo vieron, les dejo el link aquí abajo:

He de confesar que cuando lo vi tuvo gracia, sin embargo lo recordé hace un tiempo y volví a ver aquel gracioso video, donde se busca ridiculizar o reírse de lo que aparentemente es “raro” o “incoherente” en JS.

Nota: De una vez aclaro JS no es perfecto, como todo lenguaje tiene altibajos, nada de que preocuparse es normal.

Continuando… al verlo de nuevo un tiempo después, considerando una cierta madurez que cualquiera adquiere después de cierto tiempo de trabajar con el lenguaje, no me fue tan gracioso, la razón… sencilla el entendimiento de como funciona Javascript.

En el minuto 2:15 del vídeo podemos ver que el ponente trata de hacer una serie de operaciones “raras” hasta cierto punto en Javascript, las primeras que llamaron mi atención son:

[] + [] // '' Empty string
[] + {} // [object Object]
{} + [] // 0
{} + {} // NaN

Si esto te parece raro, te sorprende o te causa en tu mente un WTF, es porque seguramente no comprendes algo llamado “Coercion”

Javascript es un lenguaje de tipos dinámicos o como es mal llamado “débilmente tipado”, esto quiere decir que al usar las variables los tipos se resolverán al vuelo, es decir justo antes de que sean usadas, esto lo hace a través de la “Coercion”.

1 < 2 < 3; // true
3 > 2 > 1; // false

Vamos por pasos, primero tenemos que comprender que es un operador.

Operadores… que son?

Un operador es una función… si así es es una función del tipo infix o en español in-fija param1 [operator] param2 es cuando los parámetros pueden ir al rededor del nombre de la función:

1 + 1 // 1 = parámetros y + = Nombre de función

Si lo traducimos a como normalmente conocemos una función prefix o prefija, seria así:

function +(p1, p2) {}

Perfecto, ahora pasemos a comprender lo siguiente.

Precedencia y asociatividad en operadores.

En Javascript los operadores tienen un precedencia y asociatividad, que son las que rigen la forma de lectura que JS da a cada uno, para comprender el tema voy a utilizar el operador de adición o “adition operator” y “multiplication operator”.

var a = 3 + 4 * 5; // 23
var b = 3 * 4 * 5; // 60

Primero veamos la tabla de precedencia y asociatividad que tiene Javascript, la cual comparto en este link, bien de acuerdo con esa tabla nos indica que nuestros operadores tienen una precedencia y asociatividad así:

Como podemos observar Mutiplication operator tiene una precedencia mas alta que Addition, entonces, al tener la precedencia mas alta resuelve primero 4 * 5 tomando como ejemplo la variable var a para posteriormente a 3 sumar el resultado anterior3 + 20

Entonces aplicando la misma lógica el ejemplo de la variable b el resultado es un tanto diferente, ya que estamos hablando del mismo operador por lo que su precedencia es la misma, entonces, cual debería resolver primero, bueno cuando la precedencia es la misma se tiene que mirar a la asociatividad la cual nos indica que la lectura de resolución debe ser de izquierda a derecha en este caso, por lo que primero se resuelve 3*4 para luego a ese resultado multiplicarlo por 5 12 * 5 lo que nos da el resultado de 60

Bien, entendiendo este razonamiento, podemos avanzar para ahora si, entender que es la coercion.

Coercion

Ya decíamos anteriormente que la coercion es el medio por el cual Javascript trata de tipificar al vuelo los valores de cada variable, lo que hace que Javascript sea un lenguaje de tipos dinámicos a diferencia de otros lenguajes como C# que son “static typed” o de tipos estáticos.

Pero para ejemplificar como es que trabaja la coercion para nosotros automáticamente en JS, voy a utilizar el acertijo mas común en las preguntas de predicción de código en una entrevista.

1 < 2 < 3; // true
3 > 2 > 1; // false

Aparentemente lo de arriba es cosa del diablo… pero no lo es, es la coercion en acción.

Primero volvemos a recordar la precedencia y asociatividad del operador < y > y nuestra tabla nos dice:

Efectivamente, tienen una precedencia de 11 pero en ambos casos estamos hablando del mismo operador, por lo cual es necesario voltear a ver la asociatividad, la cual es de izquierda a derecha, por lo que del primer ejemplo se resuelve en un inicio 1 < 2 lo cual retorna un boolean es decir true o false entonces tenemos lo siguiente:

1 < 2 // true
true < 3

He aqui donde entra la coercion, cuando Javascript se encuentra comparando dos valores de distinto tipo, trata de ajustar o convertir uno de ellos al tipo que mejor se adapte para realizar dicha comparacion, en este caso cuando queremos comparar un boolean con un number la coercion debe entrar para convertir ese boolean en un number por lo que un false = 0 y un true = 1, teniendo esto en cuenta:

true = 1; //By coercion
1 < 3 = true //That’s it

No hay magia negra, ni brujería es simple y razonada coercion.

Derivado de esto, es que se recomienda usar === en lugar de == ya que para evitar que la coercion convierta nuestros valores para compararlos le indicamos un grado mas a la comparación haciéndola mas estricta.

let a = 0;
let b = false;
a == b; // true because false = 0 By coercion so... 0 == 0 true
a === b; // false

Ahora si, pasamos a comprender el objeto de este articulo y regresando un poco al tema del vídeo, wat JS, veamos uno de los ejemplos citados en dicho vídeo.

{} + [] // 0

Bien, recordemos que los “curly braces” cuando no son asignados a una expresión, solo son la representación de un bloque de código y en este caso vacío, entonces lo que esta intentando resolver es finalmente un array vacío para compararlo con nada, ya que al no tener un primer parámetro el operador de “Addition” se convierte en un “Unary plus”, es decir que es como si aplicáramos esto +[] lo cual gracias a la coercion es como si hiciéramos esto +0 , ya que intenta convertir un array vacío en un 0 para que pueda funcionar el “Unary plus” operator.

Ahora que hay de este ejemplo:

[] + {} // [object Object]

El resultado de esto no debería ser lo pensado por sentido “común” 0 al igual que el caso anterior ya que aquí el operador que se esta usando es un “Addition operator” el cual recibe dos parámetros a diferencia del ejemplo anterior, por lo que la coercion esta tratando de interpretar el mejor tipo para realizar una adición entre objetos convirtiendo el array en un objeto y comparándolo contra otro que no existe dando como resultado solo un objeto, a diferencia de hacer new Object() + new Object() // [object Object][object Object]

Analicemos uno mas:

{} + {} // NaN

Volvemos al tema de los “curly braces” cuando no son asignados a una expresión, solo son un bloque de código vacío, por lo que esta intentado incrementar un objeto es como hacer esto +{} //NaN that’s all.

Conclusión

Cuando entendemos el razonamiento de las cosas, el como funciona Javascript, es mucho mas fácil no solo predecir código, si no también, evitar la sorpresa o los WTF en nuestras mentes al ver vídeos como este, que si es divertido pero siempre y cuando ignores el funcionamiento de JS, de lo contrario le resta diversión.

Alguna vez alguien me pregunto si esto era necesario saberlo, si alguna vez íbamos aplicarlo en un proyecto, la respuesta es que no es algo que apliques directamente a un proyecto como un shorthand o ninja code, es algo menos abstracto, que cuando lo entiendes tienes mucho menos probabilidad de cometer un error fácil de resolver pero difícil de debuggear… eso, se traduce en, saber lo que estas haciendo.

Comprender, no imitar.

--

--