Por que {. . . .0} evaluar a {}?


80

Lo acabo de encontrar {....0}en el código de un amigo. Evaluarlo en la consola devuelve {}(objeto vacío).

¿Porqué es eso? ¿Cuál es el significado de 4 puntos en JavaScript?


11
¿Has visto casi 2500 veces en 6 horas? Parece que su amigo está usando el operador de propagación en un contexto diferente.
Jeremy Harris

Esta es más una pregunta de "cómo se analiza esta expresión". Escriba esto en la consola JS y notará que el cuarto punto tiene un color diferente ... el mismo color que cero.
Salman A


@JeremyHarris la magia de HNQ
Pac0

Respuestas:


90

En realidad, cuatro puntos no tienen ningún significado. ...es el operador de propagación y .0es la abreviatura de 0.0.

Por lo tanto, la difusión de 0 (o cualquier número) en un objeto produce un objeto vacío {}.


9
Spreading 0 (or any number) yields an empty objectno necesariamente si extiende un número en cualquier otro lugar aparte de un objeto, arrojará un error, por ejemplo, [... 0] arrojará un error.
Hitesh Kumar

2
@HiteshKumar La propagación de objetos no iterables dentro de una matriz arrojará un error, pero eso no tiene nada que ver con esta pregunta. Me refiero a la difusión de objetos mencionada. :)
NikxDa

2
NikxDa Creo que @HiteshKumar hizo un punto importante. Es mejor ser más explícito sobre los casos en los que sus declaraciones son verdaderas. Spreading 0 (or any number) in object literal yields an empty objectContiene más información útil ..
Mist

1
@Mist He actualizado la respuesta. No creo que sea necesario, pero podría ser bueno para una aclaración. ¡Gracias por la actualización!
NikxDa

1
@NikxDa gracias. Me gusta pensar que tales declaraciones son más "completas" cuando tienes la capacidad de cortarlas del contexto, pegarlas en otro lugar y aún contienen toda la información y son educativas e informativas.
Mist

56

Tres puntos en un objeto literal son una propiedad de extensión , por ejemplo:

  const a = { b: 1, c: 1 };
  const d = { ...a, e: 1 }; // { b: 1, c: 1, e: 1 }

El último punto con un 0 es un número literal que .0es el mismo que 0.0. Por lo tanto esto:

 { ...(0.0) }

distribuye todas las propiedades del objeto numérico en el objeto, sin embargo, como los números no tienen propiedades (propias), se obtiene un objeto vacío.


Me lleva a pensar: ¿puedo distribuir cualquier variable y las claves propias se distribuirán en el nuevo objeto? Funciona para Function (function x() {}), (x.k = 'v'), ({...x})// {k: 'v'}, pero no funciona paraNumber (x = 10), (x.k = 'v'), ({...x}) // {}
Niebla

3
@mist porque los números (y otras primitivas) se "encajonan" en objetos cuando se trabaja con ellos como objetos, y se "desempaquetan" directamente después. Por x.klo tanto se perderá.
Jonas Wilms

¿Qué significa exactamente "en caja"? Por ejemplo, cuando usé el operador de punto (propiedad) trabajé con el número como objeto. Si estoy en lo cierto, ese es solo un caso. ¿Hay otros casos en los que está ocurriendo el 'boxeo'? ¿Se aplica solo a los números? ¿Hay alguna razón de rendimiento o algo así? Supongo que esto es para otra pregunta, y debería estudiarla más. ¿Podrías señalarme algún libro o algo?
Niebla

1
¡Gracias! Veo por qué mi clave en el número no funciona. ¡Yayy boxeo!
Niebla

3
Los números no tienen propiedades enumerables propias . Pero tienen propiedades.
Patrick Roberts

6

En términos simples, el {...}operador de extensión en JavaScript extiende un objeto / matriz con otro.

Entonces, cuando babelifier intenta extender uno con otro, tiene que identificar si está tratando de extender una matriz o un objeto.

En el caso de array, itera sobre elementos.

En el caso de object, itera sobre las claves.

En este escenario, el babelyfier está tratando de extraer claves numbercomprobando el objeto own property callque falta para numberque devuelva el objeto vacío.


0

El operador de propagación {...}permite que los iterables se expandan. Significa que los tipos de datos que se pueden definir en forma de key-valuepares se pueden expandir. En términos de Object, llamamos par clave-valor como propiedad del objeto y su valor, mientras que en términos de arrayspodemos pensar en el índice como clave y el elemento en la matriz como su valor.

let obj = { a: 4, b: 1};
let obj2 = { ...obj, c: 2, d: 4}; // {a: 4, b: 1, c: 2, d: 4}

let arr1 = ['1', '2'];
let obj3 = { ...arr1, ...['3']}; // {0: "3", 1: "2"}

En términos de matriz, ya que toma el índice como clave, aquí reemplaza el elemento '1' arr1por '3' porque ambos tienen el mismo índice en una matriz diferente.

Con cadenas demasiado extendidas, el operador devuelve un objeto no vacío. Como cadena es una matriz de caracteres, trata la cadena como una matriz.

let obj4 = {...'hi',...'hello'}   // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
let obj5 = {...'y',...'x'}   // {0: "x" }

Pero con otros tipos de datos primitivos, devuelve un objeto vacío

con numeros

let obj6 = { ...0.0, ...55} // {}

con booleano

let obj7 = { ...true, ...false} // {}

En conclusión, los tipos de datos que se pueden tratar en forma de pares clave-valor cuando se usan con el operador de propagación {...}devuelven un objeto no vacío; de lo contrario, devuelve un objeto vacío{}

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.