javascript type-conversion

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



type-conversion (8)

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é?


¡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, no un número (puede no se convertirá en un número, amigo!) y el resto de la historia de la siguiente manera:


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);


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.

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.


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());



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

console.log(+''a'')

En minúsculas se convierte en banana .

Agregar NaN a "ba" convierte NaN en la cadena "NaN" debido a la conversión de tipo, da baNaN . Y luego hay a detrás, dando baNaNa .

El espacio entre + + 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 escribir malabares

console.log(''ba''+(+''a'')+''a'')


(''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 función toLowerCase() en el resultado.

Paso uno

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

Yendo a LR , tenemos:

  • ''b'' + ''a'' devuelve ba , esta es una 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

La aplicación de .toLowerCase() en el valor devuelto por el paso uno da:

plátano

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


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

... se evalúa como ...

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

(ver: precedencia del operador )

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

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

Aunque NaN significa "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''