PC & Mobile

Pourquoi [‘1’, ‘7’, ’11’].map (parseInt) renvoie [1, NaN, 3] en javascript

Pourquoi ['1', '7', '11'].map (parseInt) renvoie [1, NaN, 3] en javascript


???

Javascript est bizarre. Ne me crois pas? Essayez de convertir un tableau de chaînes en nombres entiers en utilisant map et parseInt. Lancez votre console (F12 sur Chrome), collez ce qui suit et appuyez sur Entrée (ou exécutez le stylet ci-dessous).

['1', '7', '11'].map (parseInt);

Au lieu de nous donner un tableau d'entiers [1, 7, 11], on se retrouve avec [1, NaN, 3]. Quoi? Pour savoir ce qui se passe réellement, nous devons d’abord aborder quelques concepts Javascript. Si vous souhaitez un TLDR, j’en ai inclus un bref résumé à la fin de cet article.

Vérité et fausseté

Voici une simple déclaration if-else en Javascript:

si vrai) {
// cela fonctionne toujours
} autre {
// ça ne marche jamais
}

Dans ce cas, la condition de l'instruction if-else est true, le bloc if est toujours exécuté et le bloc else est ignoré. Ceci est un exemple trivial car true est un booléen. Et si on mettait un non-booléen comme condition?

if ("bonjour le monde") {
// ça va courir?
console.log ("La condition est la vérité");
} autre {
// ou ca?
console.log ("La condition est falsy");
}

Essayez d’exécuter ce code dans la console de votre développeur (F12 sur Chrome). Vous devriez trouver que le bloc if s'exécute. C'est parce que l'objet string "Bonjour le monde" est la vérité.

Chaque objet Javascript est soit la vérité ou fausseté. Lorsqu'ils sont placés dans un contexte booléen, tel qu'une instruction if-else, les objets sont traités comme étant vrais ou faux en fonction de leur véracité. Alors, quels objets sont la vérité et lesquels sont de la fausseté? Voici une règle simple à suivre:

Toutes les valeurs sont la vérité sauf pour: faux, 0, "" (chaîne vide), nul, indéfini, et NaN.

Confusément, cela signifie que la chaîne "faux", la ficelle "0", un objet vide {}et un tableau vide [] sont tous la vérité. Vous pouvez vérifier cela en passant un objet dans la fonction booléenne (par exemple, Booléen ("0");).

Pour nos besoins, il suffit de rappeler que 0 c'est de la fausseté.

Base

0 1 2 3 4 5 6 7 8 9 dix

Lorsque nous comptons de zéro à neuf, nous avons différents symboles pour chacun des nombres (0 à 9). Cependant, une fois que nous atteignons dix, nous avons besoin de deux symboles différents (1 et 0) pour représenter le nombre. En effet, notre système de comptage décimal a une base (base) de dix.

Radix est le plus petit nombre qui ne peut être représenté que par plusieurs symboles. Différents systèmes de comptage ont des bases différentes, de sorte que les mêmes chiffres peuvent faire référence à des numéros différents dans les systèmes de comptage.

HEXADECIMAL BINAIRE DECIMAL
RADIX = 10 RADIX = 2 RADIX = 16
0 0 0
1 1 1
2 10 2
3 11 3
4 100 4
5 101 5
6 110 6
7 111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F
16 10000 10
17 10001 11

Par exemple, en regardant le tableau ci-dessus, nous voyons que les mêmes chiffres 11 peuvent signifier différents numéros dans différents systèmes de comptage. Si la base est 2, il s'agit du nombre 3. Si la base est 16, il se réfère au nombre 17.

Vous avez peut-être remarqué que, dans notre exemple, parseInt renvoyait 3 lorsque l'entrée avait la valeur 11, ce qui correspond à la colonne Binary du tableau ci-dessus.

Arguments de fonction

Les fonctions en Javascript peuvent être appelées avec un nombre quelconque d'arguments, même s'ils ne correspondent pas au nombre de paramètres de fonction déclarés. Les arguments manquants sont traités comme des arguments non définis et les arguments supplémentaires sont ignorés (mais stockés dans l'objet arguments de type tableau).

fonction foo (x, y) {
console.log (x);
console.log (y);
}
toto (1, 2); // journaux 1, 2
foo (1); // journaux 1, non défini
toto (1, 2, 3); // journaux 1, 2

carte()

Nous y sommes presque!

Map est une méthode du prototype de tableau qui renvoie un nouveau tableau des résultats de la transmission de chaque élément du tableau d'origine à une fonction. Par exemple, le code suivant multiplie par 3 chaque élément du tableau:

fonction multiplyBy3 (x) {
retourne x * 3;
}
const résultat = [1, 2, 3, 4, 5].map (multiplyBy3);
console.log (résultat); // journaux [3, 6, 9, 12, 15];

Maintenant, disons que je veux connecter chaque élément en utilisant carte() (sans déclaration de retour). Je devrais pouvoir passer console.log comme argument dans carte()… droite?

[1, 2, 3, 4, 5].map (console.log);

Quelque chose de très étrange se passe. Au lieu de ne consigner que la valeur, chaque console.log call a également enregistré l’index et le tableau complet.

[1, 2, 3, 4, 5].map (console.log);
// Ce qui précède est équivalent à
[1, 2, 3, 4, 5].carte(
(val, index, array) => console.log (val, index, array)
)
// et non équivalent à
[1, 2, 3, 4, 5].carte(
val => console.log (val)
)

Quand une fonction est passée dans carte()pour chaque itération, trois arguments sont passés dans la fonction: valeur actuelle, currentIndexet le plein tableau. C'est pourquoi trois entrées sont enregistrées pour chaque itération.

Nous avons maintenant toutes les pièces nécessaires pour résoudre ce mystère.

Le rassembler

ParseInt prend deux arguments: chaîne et base. Si la base fournie est fausseté, alors par défaut, la base est définie sur 10.

parseInt ('11 '); => 11
parseInt ('11 ', 2); => 3
parseInt ('11 ', 16); => 17
parseInt ('11 ', non défini); => 11 (radix est faux)
parseInt ('11 ', 0); => 11 (radix est faux)

Examinons maintenant notre exemple, étape par étape.

['1', '7', '11'].map (parseInt); => [1, NaN, 3]
// Première itération: val = '1', index = 0, array = ['1', '7', '11']
parseInt ('1', 0, ['1', '7', '11']) => 1

Puisque 0 est faux, la base est définie sur la valeur par défaut 10. parseInt () prend seulement deux arguments, donc le troisième argument ['1', '7', '11'] est ignoré. La ficelle '1' dans la base 10 se réfère au nombre 1.

// Deuxième itération: val = '7', index = 1, array = ['1', '7', '11']
parseInt ('7', 1, ['1', '7', '11']) => NaN

Dans un système à base 1, le symbole '7' n'existe pas. Comme avec la première itération, le dernier argument est ignoré. Alors, parseInt () résultats NaN.

// Troisième itération: val = '11', index = 2, array = ['1', '7', '11']
parseInt ('11 ', 2, ['1', '7', '11']) => 3

Dans un système à base 2 (binaire), le symbole '11' fait référence au nombre 3. Le dernier argument est ignoré.

Résumé (TLDR)

['1', '7', '11'].map (parseInt) ne fonctionne pas comme prévu car carte passe trois arguments dans parseInt () à chaque itération. Le deuxième argument indice est passé à parseInt en tant que base paramètre. Ainsi, chaque chaîne du tableau est analysée à l'aide d'une base différente. '7' est analysé comme la base 1, qui est NaN, '11' est analysé en tant que base 2, qui est 3. '1' est analysé comme la base par défaut 10, car son index 0 est fausseté.

Et ainsi, le code suivant fonctionnera comme prévu:

['1', '7', '11'].map (numStr => parseInt (numStr));
Show More

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Related Articles

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Close
Close