web-dev-qa-db-fra.com

Pourquoi le résultat de ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'banana'?

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?

571
HV Sharma
'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'
87
Tyler Roper
('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.

La première étape

'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 .

Étape deux

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.

35
Taslim Oseni

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:

  1. Numéro (chaîne);
  2. + chaîne;

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);
24
Neel Rathod

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.

9
Travis J

L'utilisation de + convertira n'importe quelle valeur en nombre en JavaScript!

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:

Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase()'banana'?

7
Alireza

enter image description here

En savoir plus sur NaN sur W3Schools ou Mozilla Developer Network

2
rprakash

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());
0
Rakibul Islam