Czy zadanie z przecinkiem działa?

108

Dlaczego aaa = 1,2,3działa i ustawia wartość aaana 1?

Dlaczego nie var bbb = 1,2,3działa?

Dlaczego var bbb = (1,2,3)działa i ustawia wartość bbbna 3?

Przykładowa sesja konsoli

Shankar Cabus
źródło
9
Pojawia się błąd składni, ponieważ nazwy zmiennych nie mogą zaczynać się od liczby. var a1,a2,a3;po prostu zadeklaruje trzy zmienne lokalne.
Jared Farrish

Odpowiedzi:

200

Dużo się tu dzieje, ale w zasadzie wszystko sprowadza się do operatora przecinka .

Operator przecinka ocenia oba swoje operandy (od lewej do prawej) i zwraca wartość drugiego operandu.


Ten kod:

aaa = 1,2,3

Jest równa:

aaa = 1;
2;
3;

So aaajest niejawnie zadeklarowana i przypisana do wartości 1. Zwróć uwagę, że wynik na konsoli jest wynikiem ostatniej instrukcji 3.


Ten kod:

var bbb = 1,2,3

Jest błędem składniowym, ponieważ przecinki w deklaracjach zmiennych są używane do deklarowania wielu zmiennych w jednym wierszu. Jak wskazuje artykuł w MDN,

Zauważ, że przecinek w varinstrukcji nie jest operatorem przecinka, ponieważ nie istnieje w wyrażeniu. Jest to raczej znak specjalny w varinstrukcjach, łączący wiele z nich w jedno.

Więc ten kod jest z grubsza równoważny z:

var bbb = 1;
var 2;
var 3;

Oczywiście 2nie jest prawidłowym identyfikatorem, więc w tym momencie nie działa.


Ten kod:

var bbb = (1,2,3)

Jest bardzo podobny do pierwszego, z wyjątkiem tego, że wartości liczbowe są zawarte w nawiasach, są one oceniane jako pierwsze. Więc jest to z grubsza równoważne z:

1;
2;
var bbb = 3;
pswg
źródło
17
Co więcej, =in var bbb = 1;nie jest tym samym, =co in aaa = 1;- pochodzą z różnych produkcji (Initialiser vs AssignmentExpression) w gramatyce i po prostu używają tego samego tokena.
Ryan Cavanaugh
7
Bardzo ładne wyjaśnienie. Co nie było całkowicie jednoznaczne, że a = 1, 2, 3może być w nawiasach jako (a = 1), 2, 3rozpoznawaną jak a = 1; 2; 3(i zwraca 3, na przykład b = (a = 1, 2, 3)by przypisać 3 do B). W przeciwieństwie do tego, zwraca a = (1, 2, 3)wartość jako 1; 2; a = 3i zwraca 3.
CompuChip
Co MDN mówi o parenach w przypisywaniu zmiennych i dlaczego jest odwrotnie? Nie mogłem znaleźć doc
Brian
@staticx Tak naprawdę nic nie dzieje się „na odwrót”. Nawiasy są oceniane jako pierwsze. Tak jak wtedy, gdy masz (1 + 2) * 3, 1 + 2najpierw jest oceniane, a wynik tego wyrażenia jest zastępowany z powrotem w zewnętrznym wyrażeniu do końca oceny.
pswg
9

Przecinek ma wiele zastosowań w JavaScript. W wyrażeniu:

a = 1, 2, 3;

jest to operator, który po prostu zwraca prawy argument. Ale jest to również część składni vardeklaracji, którymi są:

var var1 [ = val1 ], var2 [ = val2 ], var3 [ = val3 ], ...;

(gdzie [...]oznacza, że ​​ta część jest opcjonalna). W Twojej vardeklaracji brakuje nazw zmiennych po przecinkach, więc nie jest ona analizowana. Możesz uzyskać pożądany efekt dzięki:

var a = (1, 2, 3);

Nawiasy powodują, że przecinki są traktowane jako operatory, a nie jako separatory między deklaracjami zmiennych.

Barmar
źródło
7

W twoich przykładach przecinek jest używany w dwóch kontekstach:

var komunikat

Składnia varinstrukcji jest następująca:

var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];

Tutaj przecinek jest używany do oddzielania par nazwa-wartość zmiennej. Poniższe nie zadziała, ponieważ nazwa zmiennej nie może zaczynać się od cyfry (zobacz nazwy identyfikatorów ):

var bbb = 1, 2, 3;
// SyntaxError: Unexpected number

Operator przecinka

Operator przecinka ocenia oba swoje operandy (od lewej do prawej) i zwraca wartość drugiego operandu. Następujące wyrażenia działają w następujący sposób:

aaa = 1, 2, 3;
  • aaa = 1, 2 daje 2
    • zauważ, że aaa = 1jest oceniany jako pierwszy, ponieważ =ma wyższy priorytet niż,
  • 2, 3 daje 3
var bbb = (1, 2, 3);
  • ekspresja (1, 2, 3) daje 3jak opisano powyżej
  • Zmiennej bbbprzypisywana jest wartość3
Salman A
źródło
2
aaa = 1, 2, 3=> Operator przecinek służy do oddzielenia 3 następujących instrukcji: aaa=1, 2i 3. Wynikiem operatora przecinka jest wartość ostatniej instrukcji 3. Jednak aaa ma przypisaną wartość 1, co wyraźnie widać na zrzucie ekranu PO. Powodem tego jest pierwszeństwo operatora, przy czym operator przecinka ma najniższy priorytet.
Tibos
1

W pierwszym przypadku:

aaa = 1,2,3

przecinki służą jako separatory wyrażeń. Wykonuje przypisanie do aaa, następnie oblicza 2i odrzuca je, a następnie oblicza3 i odrzuca.

W sekundę:

var bbb = 1,2,3

varKluczowe informuje kompilator Javascript, że następną rzeczą po ,powinny być inna nazwa zmiennej. Nie znajduje się, więc umiera i dławia się.

var bbb = (1,2,3)

Tutaj kompilator najpierw go ocenia 1i ignoruje. Następnie ocenia go 2i ignoruje. Następnie oblicza 3i to pozostaje na stosie, więc jest przypisanebbb

Chociaż używanie przecinków do oddzielania wyrażeń nie jest powszechne, czasami jest to przydatne w przypadku takich rzeczy, jak forwygląd.

for (i = 0, l = 10; i < l; i++) {
  console.log(i);
}
Jeremy J Starcher
źródło