subtelne różnice między JavaScript i Lua [zamknięte]

121

Po prostu uwielbiam JavaScript. Jest taki elegancki (wyobraź sobie cichy dźwięk westchnienia zakochanego fanboya w tle).

Tak więc ostatnio grałem z Lua przez framework löve2d (fajnie!) - i myślę, że Lua też jest świetny. Tak, jak ja to widzę, te dwa języki są bardzo podobne.

Są na przykład oczywiste różnice

  • składnia
  • problematyczna domena
  • biblioteki
  • typy (trochę)

ale które są bardziej subtelne? Czy jest coś, co koder JavaScript wziąłby za pewnik, co działa w Lua tylko trochę inaczej? Czy są jakieś pułapki, które mogą nie być oczywiste dla doświadczonego programisty jednego języka próbującego drugiego?

Na przykład: w Lua tablice i hashe nie są oddzielne (są tylko tabele) - w JavaScript są to tablice numeryczne i haszowane obiekty. Cóż, jest to jedna z bardziej oczywistych różnic.

Ale czy są różnice w zmiennym zakresie, niezmienności lub czymś w tym rodzaju?

stefs
źródło
8
Dla takich jak ja, którzy szukali ogólnego porównania i trafili tutaj przypadkowo, poniżej znajduje się ładny przegląd: phrogz.net/lua/LearningLua_FromJS.html
Tao
To jest trzyczęściowa seria wyjaśniająca wszystkie różnice, które musisz znać, aby zacząć: oreilly.com/learning/ ...
charAt

Odpowiedzi:

189

Jeszcze kilka różnic:

  • Lua ma natywne wsparcie dla coroutines .
    • AKTUALIZACJA : JS zawiera teraz słowo kluczowe yield wewnątrz generatorów, dając mu wsparcie dla coroutines.
  • Lua nie konwertuje między typami dla żadnych operatorów porównania. W JS tylko ===i !==nie wpisuj juggle.
  • Lua ma operator potęgowania ( ^); JS tego nie robi. JS używa różnych operatorów w tym trójskładnikowego operatora warunkowego ( ?:vs and/or), oraz od 5,3, bitowe operatorów ( &, |itp porównaniu metamethods ).
    • UPDATE : JS ma teraz operator potęgowania **.
  • JS ma inkrementację / dekrementację, operatory typu ( typeofiinstanceof ), dodatkowe operatory przypisania i dodatkowe operatory porównania.
  • W JS , że ==, ===, !=a !==operatorzy mają niższy priorytet niż >, >=, <, <=. W Lua wszystkie operatory porównania mają ten sam priorytet .
  • Lua obsługuje rozmowy ogonowe .
  • Lua obsługuje przypisywanie do listy zmiennych . Chociaż nie jest to jeszcze standardem w Javascript , silnik JS Mozilli (i do pewnego stopnia Opera) obsługuje podobną funkcję od JS 1.7 (dostępną jako część Firefox 2) pod nazwą „ Destruising assignment ”. Destrukturyzacja w JS jest bardziej ogólna, ponieważ może być używana w kontekstach innych niż przypisanie, takich jak definicje funkcji i wywołania oraz inicjatory pętli . Przypisanie destrukturyzujące było przez jakiś czas proponowanym dodatkiem do ECMAScript (standardu języka stojącego za Javascriptem).
    • AKTUALIZACJA : Destrukturyzacja (i przypisanie destrukcji) jest teraz częścią specyfikacji ECMAScript - już zaimplementowana w wielu silnikach.
  • W Lua możesz przeciążać operatorów .
  • W Lua , można manipulować ze środowisk getfenvisetfenv w Lua 5.1 lub _ENVw Lua 5.2 i 5.3 .
  • W JS wszystkie funkcje są wariadyczne. W Lua funkcje muszą być jawnie zadeklarowane jako wariadyczne .
  • Foreachw pętlach JS nad właściwościami obiektu. Foreach w Lua (które używają słowa kluczowego for) przechodzi przez iteratory i jest bardziej ogólne.
    • AKTUALIZACJA : JS ma teraz również Iterables , z których wiele jest wbudowanych w zwykłe struktury danych, których można się spodziewać, takie jak Array. Można je zapętlić za pomocą for...ofskładni. W przypadku zwykłych obiektów można zaimplementować własne funkcje iteratora. To znacznie zbliża go do Lua.
  • JS ma zasięg globalny i funkcjonalny. Lua ma zasięg globalny i blokowy . Struktury sterujące (np if, for, while) wprowadzenie nowych bloków .

    • Ze względu na różnice w regułach określania zakresu odwołanie zamknięcia do zmiennej zewnętrznej (zwanej „wyższymi wartościami” w języku Lua) może być obsługiwane inaczej w Lua i Javascript . Jest to najczęściej spotykane w przypadku zamykania forpętli i zaskakuje niektórych. W JavaScript , treść forpętli nie wprowadza nowego zakresu, więc wszystkie funkcje zadeklarowane w treści pętli odwołują się do tych samych zmiennych zewnętrznych . W Lua każda iteracja forpętli tworzy nowe zmienne lokalne dla każdej zmiennej pętli.

      local i='foo'
      for i=1,10 do
        -- "i" here is not the local "i" declared above
        ...
      end
      print(i) -- prints 'foo'

      Powyższy kod jest równoważny z:

      local i='foo'
      do
        local _i=1
        while _i<10 do
          local i=_i
          ...
          _i=_i+1
        end
      end
      print(i)

      W konsekwencji funkcje zdefiniowane w oddzielnych iteracjach mają różne wartości wyższe dla każdej zmiennej pętli, do której się odwołuje. Zobacz także odpowiedzi Nicolasa Boli na wdrażanie zamknięć w Lua? oraz „ Jaka jest poprawna semantyka domknięcia zmiennej pętli? ” oraz „ Semantyka rodzaju ogólnego dla ”.

      UPDATE : JS ma teraz zasięg blokowy. Zmienne zdefiniowane w ramach bloku letlub uwzględniające jego constzakres.

  • Literały całkowite w JS mogą być zapisane w formacie ósemkowym.
  • JS ma wyraźną obsługę Unicode, a wewnętrznie łańcuchy są kodowane w UTF-16 (więc są sekwencjami par bajtów). Różne wbudowane funkcje JavaScript używają danych Unicode, takich jak "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 i nowsze mają sekwencje ucieczki punktów kodowych Unicode w literałach łańcuchowych (z taką samą składnią jak sekwencje specjalne punktów kodowych JavaScript), a także wbudowaną utf8bibliotekę, która zapewnia podstawowe wsparcie dla kodowania UTF-8(takie jak kodowanie punktów kodowych do UTF-8 i dekodowanie UTF-8 do punktów kodowych, pobieranie liczby punktów kodowych w ciągu i iterowanie po punktach kodowych). Łańcuchy w Lua to sekwencje pojedynczych bajtów i mogą zawierać tekst w dowolnym kodowaniu lub dowolne dane binarne. Lua nie ma żadnych wbudowanych funkcji, które używają danych Unicode; zachowanie string.upperzależy od ustawień regionalnych C.
  • W Lua , not, or, andsłowa kluczowe są używane zamiast JS S” !, ||, &&.
  • Lua używa ~=dla „nierównych”, podczas gdy JS używa !==. Na przykład if foo ~= 20 then ... end.
  • Lua 5.3 i nowsze używają ~binarnego bitowego XOR, podczas gdy JS używa ^.
  • W Lua do indeksowania tabeli można użyć dowolnego typu wartości (z wyjątkiem nili NaN). W JavaScript wszystkie typy niebędące łańcuchami (z wyjątkiem Symbol) są konwertowane na łańcuchy przed użyciem do indeksowania obiektu. Na przykład, po ocenie poniższego kodu wartość obj[1]będzie "string one"w JavaScript, ale "number one"w Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • W JS przypisania są traktowane jako wyrażenia, ale w Lua tak nie jest. Zatem, JS pozwala zadania w warunkach if, whileoraz do whilesprawozdań, ale nie w Lua if, whileoraz repeat untiloświadczenia. Na przykład if (x = 'a') {}jest poprawnym JS, ale if x = 'a' do endnieprawidłowym Lua.
  • Lua zawiera cukier składniowej do deklarowania zmiennych funkcji bloku o zakresie, funkcji, które są pola i metody ( local function() end, function t.fieldname() end, function t:methodname() end). JS deklaruje je za pomocą znaku równości ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).
outis
źródło
6
w Lua operatory logiczne (and, or) zwracają jeden z argumentów. wszystkie funkcje można wywołać z dowolną liczbą parametrów; ale są dostosowane do wymaganej liczby (chyba że używasz ... 'dodatkowych argumentów')
Javier
1
@RCIX: patrz luaconf.h (aw Lua 5.2 także lparser.c i llimits.h). Maksymalne wartości lokalne / funkcja = 200 w Lua 5.1 i Lua 5.2. Max upvalues ​​/ function = 60 w Lua 5.1, 255 w Lua 5.2 (a liczba ta obejmuje również podwyższone wartości "dziedziczone przez" zamknięcia utworzone wewnątrz funkcji).
wątpliwyjim
8
Myślę, że możesz dodać do listy tablice oparte na 1, może to być dość denerwujące, gdy nie jesteś do tego przyzwyczajony.
Yann
2
Tylko nil i false są fałszywe w Lua - więc na przykład 0 jest prawdą w Lua, ale nie w js. O obsłudze Unicode: Lua 5.3 dodaje wyraźną obsługę UTF-8, a starsze wersje Lua są przyjazne dla buforów UTF-8 przechowywanych w łańcuchach (np. Możesz używać Unicode we wzorcach wyszukiwania ciągów). Obsługa Js UTF-8 nie jest idealna, ponieważ V8 wewnętrznie używa starej 16-bitowej reprezentacji, więc twoje ciągi znaków Unicode mogą skończyć się (niespodzianka!) Parami zastępczymi, które nie byłyby potrzebne w starym dobrym UTF-8 (i wygrał nie zdarza się w Lua).
Tyler,
4
Spodobała mi się ta lista, ale nie wiem, jak ~=można prowokować subtelne błędy. Może powodować błędy składniowe , ale nie są one wcale subtelne.
kikito
12

Kilka subtelnych różnic, które przynajmniej raz Cię złapią:

  • Nie równa jest napisane ~=w Lua. W JS to jest!=
  • Tablice Lua są oparte na 1 - ich pierwszy indeks to 1, a nie 0.
  • Lua wymaga dwukropka zamiast kropki do wywołania metod obiektowych. Piszesz a:foo()zamiast a.foo()

jeśli chcesz, możesz użyć kropki, ale musisz selfjawnie przekazać zmienną. a.foo(a)wygląda trochę nieporęcznie. Szczegółowe informacje można znaleźć w części Programowanie w Lua .

richq
źródło
5
użycie jako adnotacji sprawia, że ​​wygląda na to, że a.foo()umarł xD
DarkWiiPlayer
11

Szczerze mówiąc, łatwiej byłoby wymienić rzeczy, które są wspólne dla Javascript i Lua, niż wymienić różnice. Oba są dynamicznie wpisywanymi językami skryptowymi, ale to tak naprawdę wszystko. Mają zupełnie inną składnię, różne pierwotne cele projektowe, różne tryby działania (Lua jest zawsze kompilowana do kodu bajtowego i uruchamiana na maszynie wirtualnej Lua, JavaScript jest różna), lista jest długa.

DaveR
źródło
8
absolutnie. bardzo różne cele obejmują wysoki priorytet posiadania czystego języka. Javascript ma wiele historii, Lua nieustannie odrzuca wszystko, co niepożądane.
Javier
3
+1. Nie widzę nawet, jak w ogóle są podobne, z wyjątkiem faktu, że oba są używane do tworzenia skryptów (co jest zbyt oczywiste).
Sasha Chedygov
13
-1 (gdybym mógł) Są bardzo podobne na froncie projektowania języka. Lua ma po prostu więcej funkcji i jest mniejszy (także szybszy?). Myślę, że mylisz projekt języka z wyborem implementacji.
jpc
Tak, oba są prototypami OOP (nawet jeśli nie jest to wyraźnie określone za pomocą słów kluczowych prototypelub nazywania obiektów obiektów, mimo że dokładnie tym są tabele Lua), z funkcjami jako obywatelami pierwszej klasy, mimo że nie są funkcjonalne w tradycyjnym sensie (niezmienność , rozwój deklaratywny itp.),
Bojan Markovic
2
Jasne, istnieją różnice składniowe i jeśli spojrzysz na to powierzchownie, możesz dojść do wniosku, że języki są różne. Jednak posiadanie dokładnie tego samego głównego typu danych (obiekt / tabela) oraz ten sam sposób implementacji klas i dziedziczenia (coś, co dzieli bardzo niewiele innych języków) sprawia, że ​​są one niezwykle bliskie duchem. Projekt nietrywialnego programu JS byłby prawie taki sam jak w Lua.
Alex Gian,
7

Tablice i obiekty JavaScript są bliżej, niż mogłoby się wydawać. Możesz użyć notacji tablicowej, aby uzyskać dostęp do elementów dowolnego z nich, a także możesz dodać nieliczbowe indeksy do tablic. Poszczególne elementy tablicy mogą zawierać wszystko, a tablica może być rzadka. Są prawie identycznymi kuzynami.

Nosredna
źródło
1
Czy można mieć identycznych kuzynów?
jameshfisher
To ta sama struktura danych, jedyną różnicą jest deskryptor typu, dzięki czemu można je rozróżnić.
Lilith River
5
Bardziej trafnym stwierdzeniem byłoby: Tablice to obiekty ze specjalnym zachowaniem się ich składowej „długości”.
tzenes
@eegg: jasne, Cathy i Patty .
wyjazd z
3

Z czubka mojej głowy

Lua ...

  1. obsługuje programy
  2. nie ma ograniczenia do samego ciągu / liczby jako klucza tabeli. Wszystko działa poprawnie.
  3. obsługa błędów jest nieco niezdarna. Albo nic nie robisz, albo używasz metody pcall
  4. Myślę, że przeczytałem coś o różnicach w zakresie leksykalnym i że Lua ma lepszy.
  5. O ile dobrze pamiętam, obsługa wyrażeń regularnych w lua jest ograniczona
drganie
źródło
Lua ma mieć zakres leksykalny. JavaScript ma tylko zakres funkcji. cóż, w Mozilli i Rhino można teraz użyć „let” zamiast „var” i uzyskać odpowiedni zakres leksykalny; ale nie jest jeszcze przenośny.
Javier
1
Standardowa biblioteka ciągów Lua zawiera ograniczone funkcje dopasowywania wzorców; ale jest też LPEG (także biblioteka), która daje znacznie potężniejszy system dopasowywania, łatwy w użyciu dla pełnej gramatyki.
Javier
Stwierdziłem, że LUA ma „lepszy” zakres leksykalny niż javascript, a nie javascript.
jitter
1
LPEG to dodatkowa biblioteka, co oznacza, że ​​obsługa podstawowych wyrażeń regularnych jest ograniczona do mnie
jitter
istnieje pewne ograniczenie między kluczami łańcuchowymi i klawiszami numerycznymi, użycie obu w tej samej tabeli bardzo szybko się komplikuje, ponieważ # zwraca długość tabeli, a nie liczbę ponumerowanych indeksów, co będzie kolidować z dowolnym wpisem w słowniku (indeksowanie zerowe po wyliczeniu indeksy tabel)
Weeve Ferrelaine
3

Podobało mi się to pytanie i udzielone odpowiedzi. Dodatkowe powody, dla których te dwa języki wydają mi się bardziej podobne niż nie:

Oba przypisują funkcje do zmiennych, mogą budować funkcje w locie i definiować domknięcia.

WeakPointer
źródło
1

Lua i JavaScript są prototypowymi językami bazowymi.


źródło
1
Jest to oczywiste podobieństwo między tymi dwoma językami, a także ich użycie tabel / skrótów jako głównego typu danych. Gdybyś miał stworzyć program w Javascript w sposób idiomatyczny, przyjąłbyś prawie takie samo podejście, jak w Lua. Nie zrobiłbyś tego samego w żadnym innym języku (chyba że jest to język oparty na dziedziczeniu protokołów i tabelach). To jest ogromne podobieństwo. Reszta, szczegóły dotyczące pomniejszej składni i tak dalej, są w porównaniu z nimi dość pedantyczne.
Alex Gian,
1
Istotne różnice polegają na tym, że Jaavscript nie obsługuje koreprogramów, nie jest ściśle powiązany z C i nie nadaje się jako język osadzony. (Ile mikrokontrolery są zaprogramowane w JavaScript?) Javascript jest również dużo bałaganu, z tonami starszych pułapek i Wats ( destroyallsoftware.com/talks/wat ) - od 1:40. Lua narzuciła dość spartańską dyscyplinę. Oczywiście Javascript jest bardzo mocny w przeglądarce.
Alex Gian,
1

Test ujawnia, że ​​obecny JavaScript zwraca również obiekty, a przynajmniej ciągi z wyrażeń logicznych, takich jak lua:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Sumator
źródło