Foros del Web » Programando para Internet » Javascript »

¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Estas en el tema de ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]? en el foro de Javascript en Foros del Web. Hola, 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 ...
  #1 (permalink)  
Antiguo 10/05/2016, 00:00
 
Fecha de Ingreso: junio-2004
Mensajes: 621
Antigüedad: 19 años, 10 meses
Puntos: 25
De acuerdo ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Hola,

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:
['10','10','10','10','10'].map(parseInt)
obtienes:
Código:
[10, NaN, 2, 3, 4]
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.

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:
function miFuncion(){
  console.log(arguments);
}

['a','b'].map(miFuncion)
En este caso, vemos que para cada elemento imprime:
Cita:
["a", 0, Array[2]]
["b", 1, Array[2]]
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.

De esta forma, volviendo a nuestro problema original de
Código:
['10','10','10','10','10'].map(parseInt)
en la segunda posición del array está llamando a parseInt('10',1,Array[5]);

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:
console.log(paseInt('ff',16))
255
Así que ¿cómo se pinta 'cualquier número' en base 1? NaN
Código:
console.log(paseInt('101',1))
NaN
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:

En lugar de:
Código:
['10','10','10','10','10'].map(parseInt)
Es preferible llamar a
Código:
['10','10','10','10','10'].map(function(x){
  return parseInt(x);
})
Espero que os parezcas interesantes las reflexiones aquí compartidas.

Si alguien conoce más problemas o comportamientos parecidos a éste que lo comente pues me resultan curiosos.

Un saludo
__________________
eContento
- Mis artículos y tutoriales
- Mis jsfiddles
  #2 (permalink)  
Antiguo 10/05/2016, 04:37
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Tal vez te guíe :


https://developer.mozilla.org/es/doc...ales/Array/map
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 10/05/2016, 10:46
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

MAP te pasa 3 argumentos, como sabes, e parseInt acepta dos.
Quien no lo sabe, por desconocimiento, pues se lleva ese tipo de sorpresas.

Última edición por marlanga; 10/05/2016 a las 10:56
  #4 (permalink)  
Antiguo 11/05/2016, 01:20
 
Fecha de Ingreso: junio-2004
Mensajes: 621
Antigüedad: 19 años, 10 meses
Puntos: 25
Respuesta: ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Cita:
Iniciado por marlanga Ver Mensaje
MAP te pasa 3 argumentos, como sabes, e parseInt acepta dos.
Quien no lo sabe, por desconocimiento, pues se lleva ese tipo de sorpresas.
Cierto @marlanga, aunque JavaScript es uno de esos lenguajes en que la intuición suele funcionar muy bien, y la gente no se molesta en aprenderlo. Y cuando intentan llevar cosas a las que están acostumbrados de otros lenguajes, como patrones clásicos de orientación a objetos, se topan con sorpresas como ésta, pero lo cierto es que nunca se han molestado en aprender el lenguaje.

Sino, se darían cuenta que JavaScript no es Orientado a Objetos, si no orientado a prototipos. Y que las funciones pueden recibir un número de argumentos variable.

Ahora seguro que te parece muy natural. Pero recuerdo tus primeros post del blog de videojuegos. Si hubieras buscado una aproximación orientada a prototipos, te habría resultado más fácil. En lugar de empeñarte en reproducir POO, con propiedades privadas, herencia, y demás... que sí, se puede simular, pero JS te proporciona otras herramientas con las que trabajar.

En cualquier caso, yo era de los que me leía tus post enteros y fantaseaba con tener tiempo para ponerlos en práctica. Se echa de menos que dejaras de escribir.
__________________
eContento
- Mis artículos y tutoriales
- Mis jsfiddles
  #5 (permalink)  
Antiguo 11/05/2016, 11:14
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Este caso no tiene nada que ver con patrones clásicos de orientación a objetos. Como mucho, puede haber confusión si vienes de un lenguaje que tenga una especificación de parseInt y map distintas a las que tiene javascript, pero nada más.
__________________
github.com/xgbuils | npm/xgbuils
  #6 (permalink)  
Antiguo 11/05/2016, 11:34
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: ¿porqué ['10','10','10','10','10'].map(parseInt) da [10, NaN, 2, 3, 4]?

Cita:
Iniciado por eContento Ver Mensaje
Cierto @marlanga, aunque JavaScript es uno de esos lenguajes en que la intuición suele funcionar muy bien, y la gente no se molesta en aprenderlo. Y cuando intentan llevar cosas a las que están acostumbrados de otros lenguajes, como patrones clásicos de orientación a objetos, se topan con sorpresas como ésta, pero lo cierto es que nunca se han molestado en aprender el lenguaje.

Sino, se darían cuenta que JavaScript no es Orientado a Objetos, si no orientado a prototipos. Y que las funciones pueden recibir un número de argumentos variable.

Ahora seguro que te parece muy natural. Pero recuerdo tus primeros post del blog de videojuegos. Si hubieras buscado una aproximación orientada a prototipos, te habría resultado más fácil. En lugar de empeñarte en reproducir POO, con propiedades privadas, herencia, y demás... que sí, se puede simular, pero JS te proporciona otras herramientas con las que trabajar.

En cualquier caso, yo era de los que me leía tus post enteros y fantaseaba con tener tiempo para ponerlos en práctica. Se echa de menos que dejaras de escribir.
Buff, me dejé un porrón de mini juegos sin tutoriales...
Cada dos o tres meses me acuerdo y digo de volver a retomarlo. Y así han pasado tres años xd.
No sé cuando, pero terminaré por lo menos los que dejé a medio.

Etiquetas: funcion, valor
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:09.