руйнування об'єкта без вар


97

Чому деструктурування об'єкта видає помилку, якщо varперед ним немає ключового слова?

{a, b} = {a: 1, b: 2};

кидки SyntaxError: expected expression, got '='

Наступні три приклади працюють без проблем

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

Питання про бонус: Чому нам не потрібна varдеструктуризація масиву?

Я зіткнувся з проблемою, роблячи щось подібне

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Відповіді:


158

Проблема випливає з {...}операторів, що мають багато значень у JavaScript.

Коли {з'являється на початку заяви , вона завжди буде представляти собою блок , який не може бути призначений. Якщо вона з’явиться пізніше у виписці як вираз , то вона буде представляти Об'єкт.

varДопомагає зробити це відмінність, оскільки він не може слідувати заяву , як буде угруповання дужка :

( {a, b} = objectReturningFunction() );

З їхніх документів: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

Примітки: Дужки (...) навколо оператора присвоєння потрібні при використанні об'єктного прямого деструктування без декларації.

{a, b} = {a: 1, b: 2} не є дійсним автономним синтаксисом, оскільки {a, b} з лівого боку вважається блоком, а не об'єктом буквальним.

Однак ({a, b} = {a: 1, b: 2}) є дійсним, як і var {a, b} = {a: 1, b: 2}

Вираз (...) повинен передувати крапкою з комою або він може бути використаний для виконання функції в попередньому рядку.


Якщо вона з’явиться пізніше у виписці як вираз, то вона буде представляти Об'єкт. Чи означає це, що ми ніколи не можемо мати блок-сферу в
групових

Наконечник групування дужок - чудовий.
Джеймс Сміт

Це блискуче незрозумілий шматочок знань, який мене наткнув. Це дозволяє деструктурувати по всій області дії (ну, начебто - вам все-таки потрібно оголосити свої змінні, звичайно). Але це вирішує обмеження використання ланцюжків Promise, одночасно потребуючи використання кількох змінних, вирішених з одного кроку ланцюжка Promise на іншому, не створюючи занадто багато безладу. Дякую.
Кевін Тельєр

22

Якщо ви пишете Javascript без крапки з комою , то перед синтаксисом 'призначення без оголошення' слід поставити крапку з комою, щоб вона працювала передбачувано

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

Просто хотів підкреслити це, оскільки це мене зачепило, і, сподіваюся, це може заощадити деякий час, з’ясувавши, чому це не працює, та / або дає дивні результати за допомогою таких форматорів коду prettier.

Дійсно, це насправді прямо у прийнятій відповіді (останній рядок цитованих документів), але її легко пропустити, особливо не бачачи прикладу!


1
Так. Причина, щоб люди вживали напівколонки!
jfriend00

0

Ось ще один спосіб:

let {} = {a, b} = objectReturningFunction()

Плюси:

  • Дужки не потрібні
  • Ні крапки з комою не потрібно
  • Додаткове завдання - це гарантоване відмову (враховуючи, що ніяких дивних речей не відбувається)

Мінуси:

  • Виглядає дещо дивно, хоча, на мою думку, не дивніше, ніж !(){...}() IIFE .
  • Можливо, бентежить, чому це там. Це гарантовано відкидає людей при першій зустрічі, тому я б радив не використовувати це як разове.

Такі відчуття, як IIFE, порівнянніші ;({ a, b })ніж let {} = { ... }. Хороший трюк, хоча. :)
shuckster

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