Je pratiquais du JavaScript lorsque l'un de mes amis est tombé sur ce code JavaScript:
document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());
Le code ci-dessus répond "banana"
! Quelqu'un peut-il expliquer pourquoi?
'b' + 'a' + + 'a' + 'a'
... est évalué comme ....
('b') + ('a') + (+'a') + ('a')
(voir: priorité de l'opérateur )
(+'a')
tente de convertir 'a'
à un nombre en utilisant opérateur unaire plus . Car 'a'
n'est pas un nombre, le résultat est NaN
( "Not-A-Number" ) :
'b' + 'a' + NaN + 'a'
Bien que NaN
signifie "Pas un nombre", il s'agit toujours d'un type numérique ; lorsqu'il est ajouté à des chaînes, il concatène comme tout autre nombre:
'b' + 'a' + NaN + 'a' => 'baNaNa'
Enfin, il est en minuscule:
'baNaNa'.toLowerCase() => 'banana'
('b' + 'a' + + 'a' + 'a').toLowerCase()
Pour plus de clarté, décomposons cela en deux étapes. Tout d'abord, nous obtenons la valeur de l'expression entre parenthèses, puis nous appliquons la fonction toLowerCase()
au résultat.
'b' + 'a' + + 'a' + 'a'
En allant L-R , nous avons:
'b' + 'a'
Renvoie ba , il s'agit d'une concaténation régulière.ba + + 'a'
Tente de concaténer ba avec + 'a'
. Cependant, puisque l'opérateur unaire +
Tente de convertir son opérande en nombre, la valeur NaN est renvoyée, qui est ensuite convertie en une chaîne lorsqu'elle est concaténée avec l'original ba - résultant ainsi en baNaN .baNaN
+ 'a' renvoie baNaNa . Encore une fois, c'est une concaténation régulière.À ce stade, le résultat de la première étape est baNaNa .
L'application de .toLowerCase()
sur la valeur renvoyée par la première étape donne:
banane
Il existe de nombreux jeux de mots similaires en JavaScript que vous pouvez consulter.
C'est juste à cause de l'opérateur +.
Nous pouvons obtenir davantage de connaissances en le découpant.
=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator
Which later on try to convert next character to the number.
Par exemple
const string = '10';
Vous pouvez convertir une chaîne en nombre de 2 manières:
Revenons donc à la requête d'origine; Ici, il essaie de convertir le prochain caractère ('a') en nombre, mais tout à coup, nous avons eu une erreur NaN,
( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))
Mais il traite comme une chaîne car le caractère précédent était dans la chaîne. Alors il sera
( ('b') + ('a') + 'NaN' + ('a'))
Et enfin, il le convertit enLowerCase (), donc ce serait la banane
Si vous mettez un numéro à côté, votre résultat sera modifié.
( 'b' + 'a' + + '1' + 'a' )
Ce serait 'ba1a'
const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana'
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);
Cette ligne de code évalue une expression, puis appelle une méthode basée sur la valeur renvoyée.
L'expression ('b' + 'a' + + 'a' + 'a')
est uniquement composé de littéraux de chaîne et d'opérateurs d'addition.
- String Literals "Un littéral de chaîne est composé de zéro ou plusieurs caractères entre guillemets simples ou doubles."
- L'opérateur d'addition (+) "L'opérateur d'addition effectue la concaténation de chaînes ou l'addition numérique."
Une action implicite prise est l'appel à ToNumber sur une chaîne
- ToNumber appliqué au type de chaîne "ToNumber appliqué aux chaînes applique la grammaire à la chaîne d'entrée. Si la grammaire ne peut pas interpréter la chaîne comme une expansion de StringNumericLiteral, le résultat de ToNumber est NaN."
L'interpréteur a des règles sur la façon d'analyser l'expression, en la décomposant en ses composants d'expressions de gauche et de droite.
Étape 1: 'b' + 'a'
Expression gauche: 'b'
Valeur de gauche: 'b'
Opérateur: + (l'un des côtés d'expression est une chaîne, donc concaténation de chaîne)
Expression droite: 'a'
Valeur correcte: 'a'
Résultat: 'ba'
Étape 2: 'ba' + + 'a'
Expression gauche: 'ba'
Valeur de gauche: 'ba'
Opérateur: + (l'un des côtés d'expression est une chaîne, donc concaténation de chaîne)
Expression droite: + 'a'
(ceci évalue la valeur mathématique du caractère 'a' en supposant qu'il s'agit d'un nombre positif du signe + - le signe moins aurait également fonctionné ici indiquant un nombre négatif - ce qui donne NaN)
Valeur correcte: NaN (car l'opérateur est la concaténation de chaînes, toString est appelé sur cette valeur pendant la concaténation)
Résultat: 'baNaN'
Étape 3: 'baNaN' + 'a'
Expression gauche: 'baNaN'
Valeur de gauche: 'baNaN'
Opérateur: + (l'un des côtés d'expression est une chaîne, donc concaténation de chaîne)
Expression droite: 'a'
Valeur correcte: 'a'
Résultat: 'baNaNa'
Après cela, l'expression de regroupement a été évaluée, et toLowerCase est appelé, ce qui nous laisse avec la banane.
Alors...
La principale chose à savoir en premier lieu et à en tirer des leçons est d'utiliser +
avant toute valeur en JavaScript, convertira cette valeur en nombre , mais si cette valeur ne peut pas être convertie, le moteur JavaScript retournera NaN , ce qui signifie que pas un nombre (ne peut pas être converti en nombre, mate!) et le reste de l'histoire comme ci-dessous:
En savoir plus sur NaN sur W3Schools ou Mozilla Developer Network
Voyez la magie ici. Le deuxième plus est un opérateur unaire qui donne "NaN"
console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());