javascript - change - title property html
Obtener NaN mapeo inconsistente (3)
Estaba jugando con algún código para crear una matriz de 0
y se encontró que para un solo valor se devolvió NaN
lugar de 0
. Obtengo esto en Chrome, Node y Firefox.
¿Qué está causando que el segundo valor sea NaN
?
var arr = new Array(32).join(0).split('''').map(parseInt)
// prints [0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
console.dir(arr)
El mapeo pasa tres argumentos a su función:
- el elemento;
- el índice de ese elemento dentro de la matriz; y
- la propia matriz.
La función parseInt
examinará los dos primeros de ellos, tratando el primero correctamente como la cadena pero tratando el segundo como la base a utilizar. Cuando la base no es cero ni está en el rango inclusivo 2..36
, devuelve NaN
(1) . Si tuvieras una matriz con cuarenta elementos, también verías un montón de valores de NaN
al final:
0, NaN, 0, 0, 0, ... 0, 0, 0, NaN, NaN
También obtendría algunos resultados bastante extraños si las cadenas de números fueran distintas de cero, ya que el índice de matriz determinaría qué base se usó para interpretarlo.
Para solucionar este problema , puede proporcionar una función que traduzca lo que el map
le da a lo que parseInt
espera (un mapa, supongo que podría llamarlo):
function myParseInt(s,r,a) { return parseInt(s,10); }
var arr = new Array(32).join(0).split('''').map(myParseInt)
alert(arr)
También es posible que desee echar un vistazo a la forma en que está creando esta matriz, en realidad terminará como una matriz de tamaño 31 en lugar de 32. Si solo desea una matriz de caracteres ''0''
, puede usar:
var arr = new Array(32).fill(''0'')
Suponiendo que tenga un navegador que admita ECMAScript 2015, que es Safari, Firefox y Chrome-desktop en el momento de esta respuesta.
(1) Una base de cero es el caso predeterminado para manejar cosas como los prefijos hexadecimales.
Una base de uno no tiene sentido en un sistema puramente posicional (donde cada dígito se multiplica por una potencia de la base y se acumula) ya que el único dígito permitido sería 0
, por lo que cada valor de posición sería ese cero multiplicado por 1 n
. En otras palabras, el único número posible en un sistema base-uno sería cero.
Las bases del 2
al 36
son por lo tanto más sensibles.
Esto se debe a que la función que se pasa al map
se llamará con tres argumentos:
- El elemento de la matriz actual
- El índice de ese artículo.
- Toda la matriz
En este caso, esa función es parseInt
, que solo usa dos argumentos:
- La cadena a analizar
- El radix utilizado para analizar la cadena.
- Argumentos adicionales serán ignorados.
Por lo tanto, para el segundo elemento de la matriz (es decir, el índice 1
), la llamada será
parseInt("0", 1, ignoredArray)
Cuando el radix es 1
, se devuelve NaN
:
- Sea R = ToInt32 ( radix ).
- Si R ≠ 0, entonces
- Si R <2 o R > 36, entonces devuelve NaN .
También tenga en cuenta que si usara un número mayor como el new Array(99)
, habría visto que los NaN
comenzaban en el índice 37.
La función .map()
pasa tres argumentos a la devolución de llamada, dos de los cuales son usados por parseInt()
: el valor y el índice (el tercero es la propia matriz). Cuando el índice es 1
, cualquier cadena de dígitos será un valor no válido. La parseInt()
ignora el segundo argumento cuando es 0
.
Para elaborar: para el primer elemento, parseInt()
se llama así:
parseInt("0", 0)
porque el valor de la matriz es cero y el índice es cero. En la segunda llamada, es esto:
parseInt("0", 1)
y eso devuelve NaN
.
Tenga en cuenta que si no es demasiado exigente porque los resultados son todos enteros, puede hacer lo que está tratando de hacer con el constructor de números:
var arr = new Array(32).join(0).split('''').map(Number);
En ES2015 (el último estándar ratificado para JavaScript, que si todos somos muy buenos se implementará completamente en todos los navegadores como nuestro regalo de Navidad), puede utilizar la función .fill()
:
var arr = new Array(31).fill(0);