¿Por qué el resultado de ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'banana'?

575

Estaba practicando JavaScript cuando uno de mis amigos se encontró con este código JavaScript:

document.write(('b' + 'a' + + 'a' + 'a').toLowerCase());

¡El código anterior responde "banana"! ¿Alguien puede explicar por qué?

HV Sharma
fuente
22
Esa segunda ventaja es un operador unario: +"a"es NaN.
Gerardo Furtado
8
En una consola, escriba +'a'solo y vea qué sucede.
Algún tipo programador el
23
Y para aquellos ansiosos por más. Ver lista completa de diversión
Giddy Naya
44
Muy relacionado: stackoverflow.com/q/9032856
Kyll

Respuestas:

566

+'a'se resuelve en NaN("No es un número") porque obliga a una cadena a un número, mientras que el carácter ano se puede analizar como un número.

document.write(+'a');
En minúsculas se convierte banana.

Agregar NaNa "ba"vueltas NaNen la cadena "NaN"debido a la conversión de tipo, da baNaN. Y luego hay un atrasero, dando baNaNa.

El espacio intermedio + +es hacer que la primera concatenación de cadenas y la segunda sean un operador unario más (es decir, "positivo"). Tiene el mismo resultado si usa 'ba'+(+'a')+'a', resuelto como 'ba'+NaN+'a', que es equivalente a 'ba'+'NaN'+'a'debido al malabarismo de tipos.

document.write('ba'+(+'a')+'a');

SOFe
fuente
90
'b' + 'a' + + 'a' + 'a'

... se evalúa como ...

('b') + ('a') + (+'a') + ('a')

(ver: precedencia del operador )

(+'a')intenta convertir 'a'a un número utilizando el operador unario más . Como 'a'no es un número, el resultado es NaN ( "No es un número" ):

'b'  +  'a'  +  NaN  + 'a'

Aunque NaNsignifica "No es un número", sigue siendo un tipo numérico ; cuando se agrega a las cadenas, se concatena como cualquier otro número:

'b'  +  'a'  +  NaN  + 'a'  =>  'baNaNa'

Finalmente, está en minúsculas:

'baNaNa'.toLowerCase()      =>  'banana'
Tyler Roper
fuente
36
('b' + 'a' + + 'a' + 'a').toLowerCase()

Para mayor claridad, dividamos esto en dos pasos. Primero, obtenemos el valor de la expresión entre paréntesis y luego aplicamos la toLowerCase()función en el resultado.

Paso uno

'b' + 'a' + + 'a' + 'a'

Yendo a LR , tenemos:

  • 'b' + 'a'devuelve ba , esto es concatenación regular.
  • ba + + 'a'intenta concatenar ba con + 'a'. Sin embargo, dado que el operador unario +intenta convertir su operando en un número, se devuelve el valor NaN , que luego se convierte en una cadena cuando se concatena con el ba original , lo que resulta en baNaN .
  • baNaN+ 'a' devuelve baNaNa . De nuevo, esto es concatenación regular.

En esta etapa, el resultado del primer paso es baNaNa .

Segundo paso

Aplicar .toLowerCase()sobre el valor devuelto desde el paso uno da:

plátano

Hay muchos juegos de palabras similares en JavaScript que puedes consultar.

Taslim Oseni
fuente
24

Es solo por el operador + .

Podemos obtener más conocimiento de parte de él.

=> ( ('b') + ('a') + (++) + ('a') + ('a'))
=> ( ('b') + ('a') + (+) + ('a') + ('a')) // Here + + convert it to +operator 
Which later on try to convert next character to the number.

Por ejemplo

const string =  '10';

Puede convertir una cadena en número de 2 maneras:

  1. Número (cadena);
  2. + cadena;

Así que volvamos a la consulta original; Aquí intenta convertir el siguiente carácter ('a') en el número, pero de repente recibimos el error NaN,

( ('b') + ('a') + (+'a') + ('a'))
( ('b') + ('a') + NaN + ('a'))

Pero se trata como una cadena porque el carácter anterior estaba en la cadena. Así será

( ('b') + ('a') + 'NaN' + ('a'))

Y por último lo convierte a LowCase (), por lo que sería banana

Si se le pone un número al lado, su resultado cambiará.

( 'b' + 'a' +  + '1' + 'a' ) 

Sería 'ba1a'

const example1 = ('b' + 'a' + + 'a' + 'a').toLowerCase(); // 'banana' 
const example2 = ('b' + 'a' + + '1' + 'a').toLowerCase(); // 'ba1a'
console.log(example1);
console.log(example2);

Neel Rathod
fuente
9

Esta línea de código evalúa una expresión y luego llama a un método basado en el valor devuelto.

La expresión ('b' + 'a' + + 'a' + 'a')se compone únicamente de literales de cadena y operadores de suma.

  • Literales de cadena "Un literal de cadena es cero o más caracteres encerrados entre comillas simples o dobles".
  • El operador de suma (+) "El operador de suma realiza la concatenación de cadenas o la suma numérica".

Una acción implícita tomada es la llamada a ToNumber en una cadena

  • ToNumber aplicado al tipo de cadena "ToNumber aplicado a Strings aplica gramática a la cadena de entrada. Si la gramática no puede interpretar la cadena como una expansión de StringNumericLiteral, el resultado de ToNumber es NaN".

El intérprete tiene reglas sobre cómo analizar la expresión, desglosándola en sus componentes de expresiones de mano izquierda y derecha.


Paso 1: 'b' + 'a'

Expresión izquierda: 'b'
Valor izquierdo: 'b'

Operador: + (uno de los lados de la expresión es una cadena, por lo que la concatenación de cadenas)

Expresión correcta: 'a' Valor correcto: 'a'

Resultado: 'ba'


Paso 2: 'ba' + + 'a'

Expresión izquierda: 'ba'
Valor izquierdo: 'ba'

Operador: + (uno de los lados de la expresión es una cadena, por lo que la concatenación de cadenas)

Expresión derecha: + 'a'(esto evalúa el valor matemático del carácter 'a' suponiendo que es un número positivo del signo +; el signo menos también habría funcionado aquí indicando un número negativo, lo que da como resultado NaN)
Valor correcto: NaN (debido a que el operador es la concatenación de cadenas, toString se llama a este valor durante la concatenación)

Resultado: 'baNaN'


Paso 3: 'baNaN' + 'a'

Expresión izquierda: 'baNaN'
Valor izquierdo: 'baNaN'

Operador: + (uno de los lados de la expresión es una cadena, por lo que la concatenación de cadenas)

Expresión correcta: 'a'
Valor correcto: 'a'

Resultado: 'baNaNa'


Después de esto, se ha evaluado la expresión de agrupación y se llama a toLowerCase, que nos deja con banana.

Travis J
fuente
7

¡Usar + convertirá cualquier valor a Número en JavaScript!

Entonces...

Lo principal aquí para saber primero y aprender es usar +antes de cualquier valor en JavaScript, convertirá ese valor en un número , pero si ese valor no se puede convertir, el motor de JavaScript devolverá NaN , lo que significa que no es un número (no puede se convertirá en un número, amigo!) y el resto de la historia de la siguiente manera:

¿Por qué el resultado de ('b' + 'a' + + 'a' + 'a'). ToLowerCase () 'banana'?

Alireza
fuente
0

Mira la magia aquí. El segundo plus es un operador unario que da 'NaN'

console.log(('b' + 'a' + + 'a' + 'a').toLowerCase());
console.log(('b' + 'a' + + 'a' + 'a'));
console.log(('b' + 'a' + 'a' + 'a').toLowerCase());

Rakibul Islam
fuente