Destrukturyzacja obiektów bez var


101

Dlaczego destrukturyzacja obiektów generuje błąd, jeśli przed nim nie ma varsłowa kluczowego?

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

rzuca SyntaxError: expected expression, got '='

Poniższe trzy przykłady działają bez problemów

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

Pytanie dodatkowe: dlaczego nie potrzebujemy vardo niszczenia macierzy?

Napotkałem problem, robiąc coś takiego

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

Odpowiedzi:


161

Problem wynika z tego {...}, że operatory mają wiele znaczeń w JavaScript.

Kiedy {pojawia się na początku instrukcji , zawsze będzie reprezentować blok , do którego nie można przypisać. Jeśli pojawi się później w instrukcji jako wyrażenie , będzie reprezentować Object.

varPomaga uczynić to rozróżnienie, ponieważ nie może być stosowana przez oświadczenie , jak będzie grupowanie nawias :

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

Z ich dokumentów: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destruifying_assignment#Assignment_without_declaration

Uwagi: Nawiasy (...) wokół instrukcji przypisania są wymagane, gdy używa się przypisania destrukturyzacji literału obiektu bez deklaracji.

{a, b} = {a: 1, b: 2} nie jest poprawną samodzielną składnią, ponieważ {a, b} po lewej stronie jest traktowane jako blok, a nie literał obiektowy.

Jednak ({a, b} = {a: 1, b: 2}) jest poprawne, podobnie jak var {a, b} = {a: 1, b: 2}

Twoje wyrażenie (...) musi być poprzedzone średnikiem lub może zostać użyte do wykonania funkcji w poprzednim wierszu.


Jeśli pojawi się później w instrukcji jako wyrażenie, będzie reprezentować Object. Czy to oznacza, że ​​nigdy nie możemy mieć zakresu blokowego w nawiasach grupujących
sharad_kalya

Wskazówka dotycząca nawiasów grupujących jest świetna.
James Smith,

To niesamowicie niejasna wiedza, która mnie zaskoczyła. Pozwala to na destrukturyzację w całym zakresie (no cóż, w pewnym sensie - nadal musisz zadeklarować swoje zmienne, oczywiście). Ale rozwiązuje ograniczenie korzystania z łańcuchów obietnic przy jednoczesnej potrzebie użycia wielu zmiennych rozstrzyganych z jednego etapu łańcucha obietnicy w innym, bez tworzenia zbytniego bałaganu. Dzięki.
Kevin Teljeur

24

Jeśli piszesz Javascript bez średników , składnia „przypisanie bez deklaracji” powinna być poprzedzona średnikiem, aby działała przewidywalnie

let a, b

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

Chciałem tylko to podkreślić, ponieważ mnie to zaskoczyło i mam nadzieję, że może zaoszczędzić innym trochę czasu na zastanawianiu się, dlaczego to nie działa i / lub daje dziwne wyniki z elementami formatującymi kod, takimi jak prettier.

Rzeczywiście, jest to rzeczywiście tam, w zaakceptowanej odpowiedzi (ostatnia linia cytowanych dokumentów), ale łatwe do przeoczenia, zwłaszcza bez przykładu!


1
Tak. Powód, dla którego ludzie używają średników!
jfriend00

2

Oto inny sposób:

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

Plusy:

  • Nie potrzeba nawiasów
  • Nie potrzeba średników
  • Dodatkowe zadanie jest gwarantowanym brakiem możliwości (biorąc pod uwagę, że nie dzieje się nic dziwnego)

Cons:

  • Wygląda trochę dziwnie, chociaż moim zdaniem nie dziwniej niż !(){...}() IIFE .
  • Może być niejasne, dlaczego tam jest. Gwarantuje to, że przy pierwszym spotkaniu zrzuci ludzi, więc odradzałbym używanie go jako jednorazowego.

Rodzaj Odczuwalna Iife są bardziej porównywalne ;({ a, b })niż let {} = { ... }. Niezła sztuczka. :)
licho

@ proto-n, +1, bardzo sprytny pomysł. Jak się z tym spotkałeś?
Pacerier
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.