Чому {. . . .0} оцінити до {}?


80

Я щойно знайшов {....0}у коді друга. Оцінюючи його у поверненнях консолі {}(порожній об’єкт).

Чому так? Що означає 4 крапки в JavaScript?


11
Переглядали майже 2500 разів за 6 годин? Здається, ваш друг використовує оператор поширення в іншому контексті.
Джеремі Гарріс

Це більше питання "як аналізується цей вираз". Введіть це в консолі JS, і ви помітите, що 4-та точка забарвлена ​​по-різному ... того самого кольору, що і нуль.
Salman A


@JeremyHarris the magic of HNQ
Pac0

Відповіді:


90

Чотири крапки насправді не мають значення. ...є оператором розповсюдження , і .0це скорочення від 0.0.

Поширення 0 (або будь-якого числа) в об'єкт дає порожній об'єкт, отже {}.


9
Spreading 0 (or any number) yields an empty objectнеобов’язково, якщо ви поширюєте число в будь-якому іншому місці, крім об’єкта, воно видасть помилку, наприклад [... 0] викине помилку.
Хітеш Кумар

2
@HiteshKumar Поширення неітерабельних об'єктів усередині масиву справді призведе до помилки, але це не має нічого спільного з цим питанням. Я маю на увазі згаданий розподіл об’єктів. :)
NikxDa

2
NikxDa Я думаю, що @HiteshKumar зробив важливу думку. Краще бути більш чітким щодо випадків, коли ваші твердження відповідають дійсності. Spreading 0 (or any number) in object literal yields an empty objectМістить більше корисної інформації ..
Туман

1
@Mist Я оновив відповідь. Я не думаю, що це потрібно, але це може бути корисно для роз’яснень. Дякуємо за оновлення!
NikxDa

1
@NikxDa дякую. Мені подобається думати про такі висловлювання більш "повними", коли у вас є можливість вирізати їх із контексту, вставити в інше місце, і вони все ще містять всю інформацію, а також навчальні та інформативні.
Туман

56

Три крапки в літералі об’єкта є властивістю розповсюдження , наприклад:

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

Остання крапка з 0 - це числовий літерал .0, такий самий, як 0.0. Тому це:

 { ...(0.0) }

поширює всі властивості об'єкта числа в об'єкт, однак, оскільки числа не мають жодних (власних) властивостей, ви повертаєте порожній об'єкт.


Ви наводите мене на роздуми - я можу поширити будь-яку змінну, і власні ключі будуть поширюватися на новий об’єкт? Це працює, Function (function x() {}), (x.k = 'v'), ({...x})// {k: 'v'}але не працюєNumber (x = 10), (x.k = 'v'), ({...x}) // {}
туман

3
@mist, тому що цифри (та інші примітиви) потрапляють в об'єкти, коли ви працюєте з ними як з об'єктами, і "розпаковуються" безпосередньо після цього. Тому x.kзагубишся.
Jonas Wilms

Що саме означає "в коробці"? Наприклад, коли я використовував оператор крапок (властивість), я працював із числом як об’єктом. Якщо я прав, це лише один випадок. Чи бувають інші випадки, коли відбувається "бокс"? Чи стосується це лише чисел? Є якась причина чи щось інше? Я думаю, це стосується іншого питання, і мені слід вивчити його далі. Не могли б ви вказати мені якусь книжку чи щось інше?
Туман

1
Дякую! Я розумію, чому мій ключ до номера не міг працювати. Yayy бокс!
Туман

3
Числа не мають власних незліченних властивостей. Але вони мають властивості.
Патрік Робертс,

6

Простіше кажучи, {...}оператор поширення в javascript розширює один об'єкт / масив іншим.

Отже, коли babelifier намагається розширити одне з одним, він повинен визначити, чи намагається він розширити масив чи об'єкт.

У випадку array, це ітерація над елементами.

У випадку object, це ітерація над клавішами.

У цьому випадку babelyfier намагається витягти ключі number, перевіряючи об'єкт, own property callякого немає, numberтому він повертає порожній об'єкт.


0

Оператор розповсюдження {...}дозволяє ітерабелам розширюватися. Це означає, що ті типи даних, які можна визначити у формі key-valueпар, можна розширити. З точки зору Objectми називаємо пару ключ-значення як властивість Object і це значення, тоді як з точки зору arraysми можемо думати індекс як ключ, а елемент у масиві як його значення.

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"}

З точки зору масиву, оскільки він приймає індекс як ключ, то тут він замінює елемент '1' arr1з на '3', оскільки обидва вони мають однаковий індекс в іншому масиві.

При занадто розповсюдженому рядку оператор повертає непустий об'єкт. Оскільки рядок є масивом символів, то він розглядає рядок як масив.

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

Але з іншими примітивними типами даних він повертає порожній об'єкт

з цифрами

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

з булевим

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

На закінчення ті типи даних, які можна обробляти у формі пар ключ-значення при використанні з оператором поширення, {...}повертає непустий об'єкт, інакше він повертає порожній об'єкт{}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.