subtile Unterschiede zwischen JavaScript und Lua [geschlossen]

121

Ich liebe einfach JavaScript. Es ist so elegant (stellen Sie sich das leise Geräusch eines verliebten Fanboys vor, der im Hintergrund seufzt).

Also habe ich kürzlich mit Lua über das löve2d Framework gespielt (nett!) - und ich finde Lua auch großartig. So wie ich es sehe, sind diese beiden Sprachen sehr ähnlich.

Es gibt offensichtliche Unterschiede wie

  • Syntax
  • Problemdomäne
  • Bibliotheken
  • Typen (ein bisschen)

aber welche sind die subtileren? Gibt es etwas, das ein JavaScript-Codierer für selbstverständlich hält und das in Lua nur geringfügig anders funktioniert? Gibt es Fallstricke, die für den erfahrenen Programmierer einer Sprache, die die andere versucht, möglicherweise nicht offensichtlich sind?

Beispiel: In Lua sind Arrays und Hashes nicht getrennt (es gibt nur Tabellen). In JavaScript handelt es sich um numerische Arrays und Hash-Objekte. Nun, dies ist einer der offensichtlicheren Unterschiede.

Aber gibt es Unterschiede in Bezug auf variablen Umfang, Unveränderlichkeit oder ähnliches?

Stefs
quelle
8
Für diejenigen, wie ich, die nach einem Gesamtvergleich suchten und versehentlich hier gelandet sind
Tao
Dies ist eine dreiteilige Serie, die alle Unterschiede erklärt, die Sie kennen müssen, um loszulegen: oreilly.com/learning/…
charAt 2nd

Antworten:

189

Einige weitere Unterschiede:

  • Lua hat native Unterstützung für Coroutinen .
    • UPDATE : JS enthält jetzt das Yield-Schlüsselwort in Generatoren, wodurch Coroutinen unterstützt werden.
  • Lua konvertiert für keine Vergleichsoperatoren zwischen Typen. Nur in JS ===und !==nicht Jonglieren.
  • Lua hat einen Potenzierungsoperator ( ^); JS nicht. JS verwendet verschiedene Operatoren, einschließlich der ternären bedingten Operator ( ?:vs and/or), und, wie von 5,3, Bitoperatoren ( &, |usw. vs. metamethods ).
    • UPDATE : JS hat jetzt den Exponentiationsoperator **.
  • JS verfügt über Inkrement / Dekrement, Typoperatoren ( typeofund instanceof), zusätzliche Zuweisungsoperatoren und zusätzliche Vergleichsoperatoren.
  • In JS , die ==, ===, !=und !==Betreiber von niedrigerer Priorität als >, >=, <, <=. In Lua haben alle Vergleichsoperatoren die gleiche Priorität .
  • Lua unterstützt Tail Calls .
  • Lua unterstützt die Zuordnung zu einer Liste von Variablen . Während es in Javascript noch nicht Standard ist , unterstützt die JS-Engine von Mozilla (und zum Teil die von Opera) eine ähnliche Funktion seit JS 1.7 (verfügbar als Teil von Firefox 2) unter dem Namen " Destructuring Assignment ". Die Destrukturierung in JS ist allgemeiner, da sie in anderen Kontexten als der Zuweisung verwendet werden kann, z. B. in Funktionsdefinitionen und Aufrufen sowie in Schleifeninitialisierern . Die Destrukturierungszuweisung ist seit einiger Zeit eine vorgeschlagene Ergänzung zu ECMAScript (dem Sprachstandard hinter Javascript).
    • UPDATE : Die Destrukturierung (und Destrukturierungszuweisung) ist jetzt Teil der Spezifikation für ECMAScript - bereits in vielen Engines implementiert.
  • In Lua können Sie Operatoren überladen .
  • In Lua können Sie Umgebungen mit getfenvundsetfenv in Lua 5.1 oder _ENVin Lua 5.2 und 5.3 bearbeiten .
  • In JS sind alle Funktionen variabel. In Lua müssen Funktionen explizit als variadisch deklariert werden .
  • Foreachin JS Schleifen über Objekteigenschaften. Foreach in Lua (die das Schlüsselwort verwenden for) durchläuft Iteratoren und ist allgemeiner.
    • UPDATE : JS hat jetzt auch Iterables , von denen viele in die regulären Datenstrukturen integriert sind, die Sie erwarten würden, wie z Array. Diese können mit der for...ofSyntax durchlaufen werden. Für reguläre Objekte kann man eigene Iteratorfunktionen implementieren. Dies bringt es Lua viel näher.
  • JS hat einen globalen und Funktionsumfang. Lua hat globalen und Blockbereich . Kontrollstrukturen (zB if, for, while) die Einführung neuer Blöcke .

    • Aufgrund unterschiedlicher Bereichsregeln kann die Referenzierung einer äußeren Variablen durch einen Abschluss (im Lua-Sprachgebrauch als "Upvalues" bezeichnet) in Lua und in Javascript unterschiedlich behandelt werden . Dies tritt am häufigsten bei Verschlüssen in forSchleifen auf und überrascht einige Menschen. In Javascript führt der Hauptteil einer forSchleife keinen neuen Bereich ein, sodass alle im Schleifenkörper deklarierten Funktionen auf dieselben äußeren Variablen verweisen . In Lua erstellt jede Iteration der forSchleife neue lokale Variablen für jede Schleifenvariable.

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

      Der obige Code entspricht:

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

      Infolgedessen haben Funktionen, die in separaten Iterationen definiert sind, unterschiedliche Aufwärtswerte für jede referenzierte Schleifenvariable. Siehe auch Nicolas Bolas Antworten auf die Umsetzung von Schließungen in Lua? und " Was ist die korrekte Semantik eines Abschlusses über eine Schleifenvariable? " und " Die Semantik des Generikums für ".

      UPDATE : JS hat jetzt einen Blockbereich. Variablen, die mit dem Blockumfang definiert sind letoder diesen constrespektieren.

  • Ganzzahlige Literale in JS können oktal sein.
  • JS bietet explizite Unicode-Unterstützung, und interne Zeichenfolgen werden in UTF-16 codiert (es handelt sich also um Sequenzen von Bytepaaren). Verschiedene integrierte JavaScript-Funktionen verwenden Unicode-Daten wie "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 und höher verfügen über Unicode-Codepunkt-Escape-Sequenzen in String-Literalen (mit derselben Syntax wie JavaScript-Codepunkt-Escape-Sequenzen) sowie über die integrierte utf8Bibliothek, die grundlegende Unterstützung für die UTF-8-Codierung bietet(z. B. Codieren von Codepunkten in UTF-8 und Decodieren von UTF-8 in Codepunkte, Abrufen der Anzahl der Codepunkte in einer Zeichenfolge und Durchlaufen von Codepunkten). Strings in Lua sind Sequenzen einzelner Bytes und können Text in beliebiger Codierung oder beliebigen Binärdaten enthalten. Lua verfügt über keine integrierten Funktionen, die Unicode-Daten verwenden. Das Verhalten von string.upperhängt vom Gebietsschema C ab.
  • In Lua , die not, or, andwerden anstelle der Schlüsselwörter verwendet JS ‚s !, ||, &&.
  • Lua verwendet ~=für "ungleich", während JS verwendet !==. Zum Beispiel if foo ~= 20 then ... end.
  • Lua 5.3 und höher verwenden ~für binäres bitweises XOR, während JS verwendet ^.
  • In Lua kann jeder Werttyp (außer nilund NaN) zum Indizieren einer Tabelle verwendet werden. In JavaScript werden alle Nicht-Zeichenfolgentypen (außer Symbol) in Zeichenfolgen konvertiert, bevor sie zum Indizieren eines Objekts verwendet werden. Nach der Auswertung des folgenden Codes wird der Wert von obj[1]beispielsweise "string one"in JavaScript, aber "number one"in Lua angegeben : obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • In JS werden Zuweisungen als Ausdrücke behandelt, in Lua jedoch nicht. Somit ermöglicht JS Zuweisungen in Bedingungen if, whileund do whileAussagen, aber Lua nicht in if, whileund repeat untilAussagen. Zum Beispiel if (x = 'a') {}ist gültiges JS, aber if x = 'a' do endungültiges Lua.
  • Lua hat syntaktischen Zucker zum Deklarieren block scoped Funktionsvariablen, Funktionen , die Felder sind, und Methoden ( local function() end, function t.fieldname() end, function t:methodname() end). JS deklariert diese mit einem Gleichheitszeichen ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).
outis
quelle
6
In Lua geben logische Operatoren (und, oder) eines der Argumente zurück. Alle Funktionen können mit einer beliebigen Anzahl von Parametern aufgerufen werden. werden aber auf die benötigte Anzahl eingestellt (es sei denn, Sie verwenden die ... 'extra args')
Javier
1
@RCIX: siehe luaconf.h (und in Lua 5.2 auch lparser.c und llimits.h). Maximale lokale Werte / Funktion = 200 in Lua 5.1 und Lua 5.2. Max. Aufwärtswerte / Funktion = 60 in Lua 5.1, 255 in Lua 5.2 (und diese Anzahl enthält auch Aufwärtswerte, die von innerhalb der Funktion erstellten Verschlüssen "geerbt" wurden).
Dubiousjim
8
Ich denke, Sie können der Liste 1-basierte Arrays hinzufügen. Es kann ziemlich ärgerlich sein, wenn Sie nicht daran gewöhnt sind.
Yann
2
Nur Null und Falsch sind in Lua falsch - so ist beispielsweise 0 in Lua wahr, aber nicht in js. Informationen zur Unicode-Unterstützung: Lua 5.3 bietet explizite UTF-8-Unterstützung, und ältere Lua-Versionen sind für UTF-8-Puffer in Zeichenfolgen geeignet (z. B. können Sie Unicode in Zeichenfolgensuchmustern verwenden). Js Unterstützung von UTF-8 ist nicht perfekt, da V8 intern eine alte 16-Bit-Darstellung verwendet, sodass Ihre Unicode-Zeichenfolgen möglicherweise (überraschende!) Ersatzpaare enthalten, die in gutem alten UTF-8 nicht benötigt werden (und gewonnen haben) passiert nicht in Lua).
Tyler
4
Ich liebte diese Liste, aber ich sehe nicht , wie ~=provozieren können subtile Bugs. Es kann zu Syntaxfehlern führen , die jedoch keineswegs subtil sind.
Kikito
12

Ein paar subtile Unterschiede, die Sie mindestens einmal bemerken werden:

  • Nicht gleich wird ~=in Lua geschrieben. In JS ist es!=
  • Lua- Arrays basieren auf 1 - ihr erster Index ist 1 statt 0.
  • Lua benötigt eher einen Doppelpunkt als einen Punkt, um Objektmethoden aufzurufen. Sie schreiben a:foo()statt a.foo()

Sie können einen Punkt verwenden, wenn Sie möchten, müssen die selfVariable jedoch explizit übergeben. a.foo(a)sieht etwas umständlich aus. Weitere Informationen finden Sie unter Programmieren in Lua .

richq
quelle
5
a.foo()
Wenn
11

Um ehrlich zu sein, wäre es einfacher, die Dinge aufzulisten, die Javascript und Lua gemeinsam haben, als die Unterschiede aufzulisten. Sie sind beide dynamisch typisierte Skriptsprachen, aber das ist ungefähr so ​​weit, wie Sie wirklich gehen können. Sie haben eine völlig andere Syntax, unterschiedliche ursprüngliche Entwurfsziele, unterschiedliche Betriebsmodi (Lua wird immer zu Bytecode kompiliert und auf der Lua-VM ausgeführt, Javascript variiert), die Liste geht weiter und weiter.

DaveR
quelle
8
absolut. Zu den sehr unterschiedlichen Zielen gehört eine hohe Priorität für eine saubere Sprache. Javascript hat viel historisches Gepäck, Lua wirft ständig alles ab, was unerwünscht ist.
Javier
3
+1. Ich sehe nicht einmal, wie ähnlich sie sich überhaupt sind, außer der Tatsache, dass sie beide für Skripte verwendet werden (was zu offensichtlich ist).
Sasha Chedygov
13
-1 (wenn ich könnte) Sie sind in Bezug auf das Sprachdesign sehr ähnlich. Lua hat einfach mehr Funktionen und ist kleiner (auch schneller?). Ich denke, Sie verwechseln Sprachdesign mit Implementierungsoptionen.
JPC
Ja, beide sind Prototypen von OOP (auch wenn dies nicht explizit mit Schlüsselwörtern prototypeoder der Benennung von Objekten angegeben wird, obwohl es genau das ist, was Lua-Tabellen sind), mit Funktionen als erstklassiger Bürger, obwohl sie im herkömmlichen Sinne nicht funktionsfähig sind (Unveränderlichkeit) , deklarative Entwicklung usw.),
Bojan Markovic
2
Sicher, es gibt syntaktische Unterschiede, und wenn Sie es oberflächlich betrachten, können Sie daraus schließen, dass die Sprachen unterschiedlich sind. Doch genau in mit dem gleichen Hauptdatentyp (Objekt / Tabelle) und die gleiche Art und Weise von Klassen und inherritance (etwas , dass die Umsetzung sehr wenige andere Sprachen teilen) macht sie erstaunlich nahe im Geist. Das Design eines nicht trivialen JS-Programms wäre so ziemlich das gleiche wie das eines Lua-Programms.
Alex Gian
7

JavaScript-Arrays und -Objekte sind näher als Sie vielleicht denken. Sie können die Array-Notation verwenden, um auf die Elemente eines der beiden Elemente zuzugreifen, und Sie können Arrays nicht numerische Indizes hinzufügen. Einzelne Array-Elemente können alles enthalten, und das Array kann spärlich sein. Sie sind fast identische Cousins.

Nosredna
quelle
1
Kann man identische Cousins ​​haben?
Jameshfisher
Sie haben dieselbe Datenstruktur. Der einzige Unterschied besteht im Typdeskriptor, sodass Sie sie voneinander unterscheiden können.
Lilith River
5
Eine genauere Aussage wäre: Arrays sind Objekte mit einem besonderen Verhalten ihres "Längen" -Mitglieds.
tzenes
@ Eegg: Sicher, Cathy und Patty .
Outis
3

Aus meinem Kopf

Lua ...

  1. unterstützt Coroutinen
  2. Es gibt keine Einschränkung, nur Zeichenfolge / Nummer als Schlüssel für eine Tabelle zu verwenden. Funktioniert alles.
  3. Die Fehlerbehandlung ist etwas ungeschickt. Entweder handhaben Sie nichts oder Sie verwenden die pcall- Methode
  4. Ich glaube, ich habe etwas über Unterschiede im lexikalischen Bereich gelesen und dass Lua den besseren hat.
  5. Wenn ich mich richtig erinnere, ist die Unterstützung für reguläre Ausdrücke in Lua begrenzt
Jitter
quelle
Lua hat lexikalischen Geltungsbereich. JavaScript hat nur Funktionsumfang. Nun, in Mozilla und Rhino können Sie jetzt 'let' anstelle von 'var' verwenden und den richtigen lexikalischen Bereich erhalten. aber es ist noch nicht tragbar.
Javier
1
Die Standard-String-Bibliothek von Lua enthält eingeschränkte Mustervergleichsfunktionen. Es gibt aber auch LPEG (auch eine Bibliothek), das ein viel leistungsfähigeres Matching-System bietet, das leicht für eine vollständige Grammatik verwendet werden kann.
Javier
Ich erklärte, dass LUA den "besseren" lexikalischen Umfang hat als Javascript, nicht dass es keinen hat.
Jitter
1
LPEG ist eine zusätzliche Bibliothek, was bedeutet, dass die Unterstützung von Core Regex auf mich beschränkt ist
Jitter
Es gibt eine gewisse Einschränkung zwischen Zeichenfolgenschlüsseln und Zahlenschlüsseln. Die Verwendung beider Schlüssel in derselben Tabelle wird sehr schnell unübersichtlich, da # die Tabellenlänge zurückgibt, nicht die Anzahl der nummerierten Indizes, die mit einem Wörterbucheintrag in Konflikt stehen (Indizierung null nach Aufzählung) Tabellenverzeichnisse)
Weeve Ferrelaine
3

Diese Frage und die Antworten haben mir gefallen. Weitere Gründe, warum mir die beiden Sprachen ähnlicher erscheinen als nicht:

Beide weisen Variablen Funktionen zu, können Funktionen im laufenden Betrieb erstellen und Abschlüsse definieren.

Schwacher Zeiger
quelle
1

Lua und JavaScript sind beide Prototyp-Basissprachen.


quelle
1
Dies ist die offensichtliche Ähnlichkeit zwischen den beiden Sprachen, dies und ihre Verwendung von Tabellen / Hashes als Hauptdatentyp. Wenn Sie ein Javascript-Programm idiomatisch entwickeln würden, würden Sie fast den gleichen Ansatz verfolgen wie in Lua. Sie würden dies nicht in einer anderen Sprache tun (es sei denn, es handelt sich um eine Sprache, die auf Prototypvererbung und Tabellen basiert). Dies ist eine große Ähnlichkeit. Der Rest, Details zur Nebensyntax usw. sind im Vergleich ziemlich pedantisch.
Alex Gian
1
Die wichtigen Unterschiede sind, dass Jaavscript keine Coroutinen unterstützt, nicht sehr eng mit C gekoppelt ist und sich nicht wirklich als eingebettete Sprache eignet. (Wie viele Mikrocontroller sind in Javascript programmiert?) Javascript ist auch viel chaotischer, mit Tonnen von älteren Fallstricken und WATs ( destroyallsoftware.com/talks/wat ) - ab 1:40. Lua wurde eine ziemlich spartanische Disziplin auferlegt. Javascript ist natürlich sehr stark im Browser.
Alex Gian
1

Ein Test zeigt, dass aktuelles Javascript auch Objekte oder zumindest Zeichenfolgen aus logischen Ausdrücken zurückgibt, wie es lua tut:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Addierer
quelle