El otro día un amigo me enseñó algo que vio circulando por la redes sociales y que es una de esas cosas de JavaScript que exasperan a programadores de otros lenguajes que esperan un comportamiento similar al que están acostumbrados sin profundizar en lo que hay debajo.
Y es que si abres una consola de un navegador y evalúas la siguiente expresión:
Código:
obtienes:['10','10','10','10','10'].map(parseInt)
Código:
Y claro, me preguntó ¿tú sabes por qué es? Al principio no me di cuenta, pero intuía porque era. Y no me quedó más remedio que hacer unas comprobaciones, para ver si estaba en lo cierto, y he querido compartir el resultado con vosotros, por si alguien quiere arrojar más luz.[10, NaN, 2, 3, 4]
La función map funciona de la siguiente manera: a cada elemento del array le aplica la función que recibe como argumento, en este caso parseInt. Pero map llama a esta función ¿sólo con el elemento que está tratando o con más datos? Esto lo comprobamos fácilmente definiendo una función que imprima por consola los parámetros que recibe:
Código:
En este caso, vemos que para cada elemento imprime:function miFuncion(){ console.log(arguments); } ['a','b'].map(miFuncion)
Cita:
Es decir, que map llama a miFunción con una terna de valores formada por el propio valor, por la posición que ocupa en el array, y por el propio array.["a", 0, Array[2]]
["b", 1, Array[2]]
["b", 1, Array[2]]
De esta forma, volviendo a nuestro problema original de
Código:
en la segunda posición del array está llamando a parseInt('10',1,Array[5]);['10','10','10','10','10'].map(parseInt)
Pero parseInt puede recibir un segundo parámetro opcional que es el radix, la base. Por ejemplo, sabemos que FF en hexadecimal es 255.
Código:
Así que ¿cómo se pinta 'cualquier número' en base 1? NaNconsole.log(paseInt('ff',16)) 255
Código:
Resumiendo, si no queremos trabajar nada más que con el valor, obviando la posición, y el resto del Array, podemos encapsular la llamada a la función en nuestra propia función:console.log(paseInt('101',1)) NaN
En lugar de:
Código:
Es preferible llamar a ['10','10','10','10','10'].map(parseInt)
Código:
Espero que os parezcas interesantes las reflexiones aquí compartidas.['10','10','10','10','10'].map(function(x){ return parseInt(x); })
Si alguien conoce más problemas o comportamientos parecidos a éste que lo comente pues me resultan curiosos.
Un saludo