sottili differenze tra JavaScript e Lua [chiuso]


121

Amo semplicemente JavaScript. È così elegante (immagina il suono silenzioso di un fanboy innamorato che sospira in sottofondo).

Quindi, recentemente ho giocato con Lua tramite il framework löve2d (bello!) - e penso che anche Lua sia fantastico. A mio modo di vedere, queste due lingue sono molto simili.

Ci sono differenze evidenti, come

  • sintassi
  • dominio problematico
  • librerie
  • tipi (un po ')

ma quali sono i più sottili? C'è qualcosa che un programmatore JavaScript darebbe per scontato che funzioni in Lua in modo leggermente diverso? Ci sono insidie ​​che potrebbero non essere ovvie per il programmatore esperto di una lingua che prova l'altra?

Ad esempio: in Lua, gli array e gli hash non sono separati (ci sono solo tabelle) - in JavaScript, sono array numerici e oggetti con hash. Ebbene, questa è una delle differenze più evidenti.

Ma ci sono differenze in ambito variabile, immutabilità o qualcosa del genere?


8
Per quelli, come me, che cercavano un confronto generale e sono finiti qui per caso, la seguente è una bella panoramica: phrogz.net/lua/LearningLua_FromJS.html
Tao

Questa è una serie in tre parti che spiega tutte le differenze che devi conoscere per iniziare: oreilly.com/learning/…
charAt

Risposte:


189

Altre differenze:

  • Lua ha il supporto nativo per le coroutine .
    • AGGIORNAMENTO : JS ora contiene la parola chiave yield all'interno dei generatori, dandogli il supporto per le coroutine.
  • Lua non converte tra i tipi per nessun operatore di confronto. In JS, solo ===e !==non digitare juggle.
  • Lua ha un operatore di esponenziazione ( ^); JS no. JS utilizza operatori diversi, tra cui l'operatore condizionale ternario ( ?:vs and/or), e, come di 5,3, operatori bit a bit ( &, |ecc vs metamethods ).
    • AGGIORNAMENTO : JS ora ha l'operatore di esponenziazione **.
  • JS ha incremento / decremento, operatori di tipo ( typeofe instanceof), operatori di assegnazione aggiuntivi e operatori di confronto aggiuntivi.
  • In JS , i ==, ===, !=e !==operatori di precedenza inferiore >, >=, <, <=. In Lua, tutti gli operatori di confronto hanno la stessa precedenza .
  • Lua supporta le chiamate di coda .
  • Lua supporta l' assegnazione a un elenco di variabili . Anche se non è ancora standard in Javascript , il motore JS di Mozilla (e, in una certa misura, Opera) ha supportato una funzionalità simile a partire da JS 1.7 (disponibile come parte di Firefox 2) con il nome di " assegnazione destrutturante ". La destrutturazione in JS è più generale, in quanto può essere utilizzata in contesti diversi dall'assegnazione, come definizioni e chiamate di funzioni e inizializzatori di loop . L'assegnazione di destrutturazione è stata un'aggiunta proposta a ECMAScript (lo standard linguistico dietro Javascript) per un po '.
    • AGGIORNAMENTO : La destrutturazione (e l'assegnazione della destrutturazione) fa ora parte delle specifiche per ECMAScript, già implementata in molti motori.
  • In Lua , puoi sovraccaricare gli operatori .
  • In Lua è possibile manipolare ambienti con getfenvesetfenv in Lua 5.1 o _ENVin Lua 5.2 e 5.3 .
  • In JS , tutte le funzioni sono variadiche. In Lua , le funzioni devono essere dichiarate esplicitamente come variadiche .
  • Foreachin JS esegue un ciclo sulle proprietà dell'oggetto. Foreach in Lua (che usa la parola chiave for) ripete gli iteratori ed è più generale.
    • AGGIORNAMENTO : JS ora ha anche Iterables , molti dei quali sono integrati nelle normali strutture di dati che ti aspetteresti, come Array. Questi possono essere ripetuti con la for...ofsintassi. Per oggetti normali, è possibile implementare le proprie funzioni iteratore. Questo lo avvicina molto a Lua.
  • JS ha un ambito globale e funzionale. Lua ha un ambito globale e di blocco . Le strutture di controllo (ad esempio if, for, while) introdurre nuovi blocchi .

    • A causa delle differenze nelle regole di scoping, la referenziazione di una chiusura di una variabile esterna (chiamata "upvalues" nel gergo Lua) può essere gestita in modo diverso in Lua e in Javascript . Questo è più comunemente riscontrato con chiusure in forloop e coglie alcune persone di sorpresa. In Javascript , il corpo di un filefor ciclo non introduce un nuovo ambito, quindi tutte le funzioni dichiarate nel corpo del ciclo fanno tutte riferimento alle stesse variabili esterne . In Lua, ogni iterazione del forciclo crea nuove variabili locali per ogni variabile del ciclo.

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

      Il codice sopra è equivalente a:

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

      Di conseguenza, le funzioni definite in iterazioni separate hanno upvalues ​​differenti per ogni variabile del ciclo referenziato. Vedi anche le risposte di Nicolas Bola a Implementation of closures in Lua? e " Quali sono la semantica corretta di una chiusura su una variabile di ciclo? " e " La semantica del generico per ".

      AGGIORNAMENTO : JS ha ora un ambito di blocco. Variabili definite con leto constrispettano l'ambito del blocco.

  • I letterali interi in JS possono essere in ottale.
  • JS ha un supporto Unicode esplicito e internamente le stringhe sono codificate in UTF-16 (quindi sono sequenze di coppie di byte). Diverse funzioni JavaScript integrate utilizzano dati Unicode, come "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 e versioni successive hanno sequenze di escape di punti di codice Unicode in stringhe letterali (con la stessa sintassi delle sequenze di escape di punti di codice JavaScript) così come la utf8libreria incorporata , che fornisce il supporto di base per codifica UTF-8(come codificare punti di codice in UTF-8 e decodificare UTF-8 in punti di codice, ottenere il numero di punti di codice in una stringa e iterare su punti di codice). Le stringhe in Lua sono sequenze di singoli byte e possono contenere testo in qualsiasi codifica o dati binari arbitrari. Lua non ha funzioni integrate che utilizzano dati Unicode; il comportamento di string.upperdipende dalla locale C.
  • In Lua , il not, or, andle parole chiave sono utilizzati al posto di JS 's !, ||, &&.
  • Lua usa ~=per "non uguale", mentre JS usa !==. Ad esempio if foo ~= 20 then ... end,.
  • Lua 5.3 e versioni successive utilizzano ~per XOR binario bit per bit, mentre JS utilizza ^.
  • In Lua , qualsiasi tipo di valore (eccetto nile NaN) può essere utilizzato per indicizzare una tabella. In JavaScript , tutti i tipi non stringa (eccetto Symbol) vengono convertiti in stringhe prima di essere utilizzati per indicizzare un oggetto. Ad esempio, dopo la valutazione del seguente codice, il valore di obj[1]sarà "string one"in JavaScript, ma "number one"in Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • In JS , gli incarichi sono trattati come espressioni, ma in Lua non lo sono. Così, JS permette incarichi in condizioni di if, whilee do whiledichiarazioni, ma Lua non lo fa in if, whilee repeat untille dichiarazioni. Ad esempio, if (x = 'a') {}è JS valido, ma if x = 'a' do endè Lua non valido.
  • Lua ha zucchero sintattico per dichiarare variabili di funzione blocchi ambito, funzioni che sono campi e metodi ( local function() end, function t.fieldname() end, function t:methodname() end). JS li dichiara con un segno di uguale ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).

6
in Lua, gli operatori logici (e, o) restituiscono uno degli argomenti. tutte le funzioni possono essere chiamate con un numero qualsiasi di parametri; ma sono adattati al numero necessario (a meno che non si utilizzi ... 'extra args')
Javier,

1
@RCIX: vedere luaconf.h (e in Lua 5.2, anche lparser.c e llimits.h). Max valori locali / funzione = 200 in Lua 5.1 e Lua 5.2. Max upvalues ​​/ funzione = 60 in Lua 5.1, 255 in Lua 5.2 (e questo conteggio include anche upvalues ​​"ereditati da" chiusure create all'interno della funzione).
dubiousjim

8
Penso che tu possa aggiungere array basati su 1 all'elenco, può essere piuttosto fastidioso quando non ci sei abituato.
Yann

2
Solo nil e false sono false in Lua - quindi, per esempio, 0 è true in Lua ma non in js. Informazioni sul supporto Unicode: Lua 5.3 aggiunge un supporto esplicito a UTF-8 e le versioni precedenti di Lua sono compatibili con i buffer UTF-8 contenuti in stringhe (ad esempio, è possibile utilizzare Unicode nei modelli di ricerca di stringhe). Il supporto Js di UTF-8 non è perfetto poiché V8 utilizza internamente una vecchia rappresentazione a 16 bit, quindi le tue stringhe unicode potrebbero finire con (sorpresa!) Coppie surrogate che non sarebbero necessarie nel buon vecchio UTF-8 (e ha vinto succede a Lua).
Tyler

4
Mi è piaciuta molto questa lista, ma non vedo come ~=possa provocare piccoli bug. Può provocare errori di sintassi , ma non sono affatto impercettibili.
kikito

12

Un paio di sottili differenze che ti colpiranno almeno una volta:

  • Non uguale si scrive ~=in Lua. In JS lo è!=
  • Gli array Lua sono basati su 1 : il loro primo indice è 1 anziché 0.
  • Lua richiede i due punti piuttosto che un punto per chiamare i metodi dell'oggetto. Scrivi a:foo()invece di a.foo()

puoi usare un punto se vuoi, ma devi passare la selfvariabile in modo esplicito. a.foo(a)sembra un po 'ingombrante. Vedere Programmazione in Lua per i dettagli.


5
usare il per l'annotazione fa sembrare che a.foo()sia morto xD
DarkWiiPlayer

11

Ad essere onesti sarebbe più facile elencare le cose che sono comuni a Javascript e Lua piuttosto che elencare le differenze. Sono entrambi linguaggi di scripting dinamicamente digitati, ma questo è quanto puoi davvero. Hanno una sintassi totalmente diversa, diversi obiettivi di progettazione originali, diverse modalità di funzionamento (Lua è sempre compilato in bytecode ed eseguito su Lua VM, Javascript varia), l'elenco potrebbe continuare all'infinito.


8
assolutamente. gli obiettivi molto diversi includono un'alta priorità per avere un linguaggio pulito. Javascript ha un sacco di bagaglio storico, Lua perde continuamente tutto ciò che è indesiderato.
Javier,

3
+1. Non vedo nemmeno come siano affatto simili, tranne per il fatto che sono entrambi usati per lo scripting (che è troppo ovvio).
Sasha Chedygov

13
-1 (se potessi) Sono molto simili sul fronte del design del linguaggio. Lua ha semplicemente più funzioni ed è più piccolo (anche più veloce?). Penso che confondi il design del linguaggio con le scelte di implementazione.
jpc

Sì, sono entrambi prototipi OOP (anche se non è esplicitamente dichiarato usando parole chiave prototypeo nomi di oggetti oggetti, nonostante sia esattamente quello che sono le tabelle lua), con funzioni come cittadino di prima classe nonostante non siano funzionali nel senso tradizionale (immutablility , sviluppo dichiarativo ecc.),
Bojan Markovic

2
Certo, ci sono differenze sintattiche e se la guardi superficialmente, potresti concludere che le lingue sono diverse. Tuttavia ad avere esattamente lo stesso tipo di dati principale (oggetto / tabella) e lo stesso modo di classi e inherritance (cosa che l'attuazione molto poche altre lingue condividono) li rende incredibilmente vicino nello spirito. Il design di un programma JS non banale sarebbe più o meno lo stesso di quello di un programma Lua.
Alex Gian

7

Gli array e gli oggetti JavaScript sono più vicini di quanto potresti pensare. È possibile utilizzare la notazione degli array per ottenere gli elementi di uno di essi e aggiungere indici non numerici agli array. I singoli elementi dell'array possono contenere qualsiasi cosa e l'array può essere scarso. Sono cugini quasi identici.


1
Si possono avere cugini identici?
jameshfisher

Hanno la stessa struttura dati, l'unica differenza è il descrittore del tipo in modo da poterli distinguere.
Lilith River

5
Un'affermazione più accurata potrebbe essere: gli array sono oggetti con un comportamento speciale del loro membro "length".
tzenes

@eegg: certo, Cathy e Patty .
outis

3

Dalla parte superiore della mia testa

Lua ...

  1. supporta le coroutine
  2. non ha restrizioni alla sola stringa / numero come chiave per una tabella. Tutto funziona.
  3. la gestione degli errori è un po 'goffa. O non gestisci nulla o usi il metodo pcall
  4. Penso di aver letto qualcosa sulle differenze nella portata lessicale e che Lua ha la migliore.
  5. Se ricordo bene il supporto delle espressioni regolari in lua è limitato

Lua fa avere scope lessicale. JavaScript ha solo l'ambito della funzione. beh, in Mozilla e Rhino ora puoi usare 'let' invece di 'var' e ottenere il corretto ambito lessicale; ma non è ancora portatile.
Javier,

1
La libreria di stringhe standard di Lua include funzioni limitate di corrispondenza dei modelli; ma c'è anche LPEG (anche una libreria), che fornisce un sistema di corrispondenza molto più potente, facilmente utilizzabile per una grammatica completa.
Javier,

Ho affermato che LUA ha l'ambito lessicale "migliore" di javascript non che non ne abbia.
jitter

1
LPEG è una libreria aggiuntiva, il che significa che il supporto per le espressioni regolari di base è limitato a me
jitter

c'è una certa restrizione tra i tasti stringa e i tasti numerici, l'uso di entrambi nella stessa tabella diventa disordinato molto velocemente, poiché # restituisce la lunghezza della tabella, non la quantità di indici numerati, che andrà in conflitto con qualsiasi voce del dizionario (indicizzazione nulla dopo enumerato indici della tabella)
Weeve Ferrelaine

3

Mi è piaciuta questa domanda e le risposte fornite. Ulteriori motivi per cui le due lingue sembrano più simili che non a me:

Entrambi assegnano funzioni alle variabili, possono creare funzioni al volo e definire chiusure.


1

Lua e JavaScript sono entrambi prototipi di linguaggi di base.


1
Questa è l'ovvia somiglianza tra i due linguaggi, questo e il loro uso di tabelle / hash come tipo di dati principale. Se dovessi sviluppare un programma Javascript in modo idiomatico, adotteresti praticamente lo stesso approccio che faresti in Lua. Non faresti lo stesso in un'altra lingua (a meno che non si tratti di una lingua basata sull'ereditarietà del prototipo e sulle tabelle). Questa è un'enorme somiglianza. Il resto, i dettagli sulla sintassi minore e così via sono piuttosto pedanti in confronto.
Alex Gian

1
Le differenze importanti sono che Jaavscript non supporta le coroutine, non è strettamente accoppiato con C e non è realmente adatto come linguaggio incorporato. (Quanti microcontrollori sono programmati in Javascript?) Javascript è anche molto più disordinato, con tonnellate di trucchi legacy e wats ( destroyallsoftware.com/talks/wat ) - da 1:40. A Lua è stata imposta una disciplina piuttosto spartana. Javascript, ovviamente, è molto potente nel browser.
Alex Gian

1

Un test rivela che l'attuale Javascript restituisce anche oggetti, o almeno stringhe da espressioni logiche come fa lua:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.