web-dev-qa-db-fra.com

différences subtiles entre JavaScript et Lua

J'adore simplement JavaScript. C'est tellement élégant (imaginez le son calme d'un fanboy amoureux qui soupire en arrière-plan).

Donc, récemment, j'ai joué avec Lua via le framework löve2d (Nice!) - et je pense que Lua est également génial. À mon avis, ces deux langues sont très très similaires.

Il y a des différences évidentes, comme

  • syntaxe
  • domaine problématique
  • bibliothèques
  • types (un peu)

mais quels sont les plus subtils? Y a-t-il quelque chose qu'un codeur JavaScript prendrait pour acquis qui fonctionne dans Lua juste légèrement différent? Y a-t-il des écueils qui peuvent ne pas être évidents pour le codeur expérimenté d'une langue essayant l'autre?

Par exemple: dans Lua, les tableaux et les hachages ne sont pas séparés (il n'y a que des tableaux) - en JavaScript, ce sont des tableaux numériques et des objets hachés. Eh bien, c'est l'une des différences les plus évidentes.

Mais y a-t-il des différences de portée variable, d'immuabilité ou quelque chose comme ça?

120
stefs

Quelques différences supplémentaires:

  • Lua a un support natif pour coroutines .
    • [~ # ~] mise à jour [~ # ~] : JS contient désormais le mot-clé yield dans les générateurs, lui permettant de prendre en charge les coroutines.
  • Luane convertit pas entre les types pour les opérateurs de comparaison. Dans JS, seuls === Et !== Ne tapent pas jongler.
  • Lua a un opérateur d'exponentiation (^); [~ # ~] js [~ # ~] non. [~ # ~] js [~ # ~] utilise différents opérateurs, y compris l'opérateur conditionnel ternaire (?: vs and/or), et, à partir de 5.3 , opérateurs au niveau du bit (&, |, etc. vs métaméthodes ).
    • [~ # ~] mise à jour [~ # ~] : JS a maintenant l'opérateur d'exponentiation **.
  • [~ # ~] js [~ # ~] a incrémentation/décrémentation, opérateurs de type (typeof et instanceof), opérateurs d'affectation supplémentaires et opérateurs de comparaison supplémentaires .
  • Dans [~ # ~] js [~ # ~], le ==, ===, != Et !== les opérateurs ont une priorité inférieure à >, >=, <, <=. Dans Lua, tous les opérateurs de comparaison sont les même priorité .
  • Lua prend en charge appels de queue .
  • Lua prend en charge affectation à une liste de variables . Bien qu'il ne soit pas encore standard dans Javascript, le moteur JS de Mozilla (et Opera, dans une certaine mesure) a pris en charge une fonctionnalité similaire depuis JS 1.7 (disponible dans le cadre de Firefox 2) sous le nom " affectation déstructurante ". La déstructuration dans JS est plus générale, car elle peut être utilisée dans des contextes autres que l'affectation, tels que définitions de fonction et appels et initialiseurs de boucle . Affectation destructrice a été un ajout proposé à ECMAScript (la norme de langage derrière Javascript) pendant un certain temps.
    • [~ # ~] mise à jour [~ # ~] : la déstructuration (et l'affectation de la déstructuration) fait désormais partie des spécifications d'ECMAScript - déjà implémentée dans de nombreux moteurs .
  • Dans Lua, vous pouvez opérateurs de surcharge .
  • Dans Lua, vous pouvez manipuler des environnements avec getfenv et setfenv dans Lua 5.1 ou _ENV Dans - Lua 5.2 et 5. .
  • Dans [~ # ~] js [~ # ~], toutes les fonctions sont variadiques. Dans Lua, les fonctions doivent être explicitement déclarées comme variadic .
  • Foreach in [~ # ~] js [~ # ~] fait une boucle sur les propriétés des objets. Foreach in Lua (qui utilise le mot clé for) fait une boucle sur les itérateurs et est plus général.
    • [~ # ~] mise à jour [~ # ~] : JS a Iterables maintenant aussi, dont beaucoup sont intégrés dans le les structures de données normales que vous attendez, telles que Array. Ceux-ci peuvent être bouclés avec la syntaxe for...of. Pour les objets réguliers, on peut implémenter leurs propres fonctions d'itérateur. Cela le rapproche beaucoup plus de Lua.
  • JS a une portée globale et fonctionnelle. Lua a portée globale et bloc . Les structures de contrôle (par exemple if, for, while) introduisent de nouveaux blocs .

    • En raison de différences dans les règles de portée, le référencement d'une fermeture d'une variable externe (appelée "upvalues" dans le langage Lua) peut être géré différemment dans Lua et dans Javascript. Cela se produit le plus souvent avec fermetures dans les boucles for , et surprend certaines personnes par surprise. Dans Javascript, le corps d'une boucle for n'introduit pas de nouvelle portée, donc toutes les fonctions déclarées dans le corps de la boucle référencent toutes les mêmes variables externes . Dans Lua, chaque itération de la boucle for crée de nouvelles variables locales pour chaque variable de boucle.

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

      Le code ci-dessus est équivalent à:

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

      Par conséquent, les fonctions définies dans des itérations distinctes ont des valeurs de hausse différentes pour chaque variable de boucle référencée. Voir aussi les réponses de Nicolas Bola à Implémentation des fermetures dans Lua? et " Quelle est la sémantique correcte d'une fermeture sur une variable de boucle? ", et " Le Sémantique du générique pour ".

      [~ # ~] mise à jour [~ # ~] : JS a maintenant une portée de bloc. Les variables définies avec let ou const respectent la portée du bloc.

  • Les littéraux entiers dans [~ # ~] js [~ # ~] peuvent être en octal.
  • [~ # ~] js [~ # ~] a un support Unicode explicite, et les chaînes internes sont encodées en TF-16 (donc ce sont des séquences de paires d'octets ). Diverses fonctions JavaScript intégrées utilisent des données Unicode, telles que "pâté".toUpperCase() ("PÂTÉ"). Lua 5.3 et plus ont des séquences d'échappement de point de code Unicode dans des littéraux de chaîne (avec la même syntaxe que les séquences d'échappement de point de code JavaScript) ainsi que la bibliothèque utf8 Intégrée, qui fournit une prise en charge de base pour encodage UTF-8 (comme le codage de points de code en UTF-8 et le décodage d'UTF-8 en points de code, l'obtention du nombre de points de code dans une chaîne et l'itération sur des points de code ). Les chaînes en Lua sont des séquences d'octets individuels et peuvent contenir du texte dans n'importe quel codage ou des données binaires arbitraires. Lua n'a pas de fonctions intégrées qui utilisent des données Unicode; le comportement de string.upper dépend des paramètres régionaux C.
  • Dans Lua, les mots clés not, or, and sont utilisés à la place de [~ # ~] js [ ~ # ~]'s !, ||, &&.
  • Lua utilise ~= Pour "différent", tandis que [~ # ~] js [~ # ~] utilise !==. Par exemple, if foo ~= 20 then ... end.
  • Lua 5.3 et plus, utilisez ~ Pour XOR binaire au niveau du bit, tandis que [~ # ~] js [~ # ~] utilise ^.
  • Dans Lua, tout type de valeur (sauf nil et NaN) peut être utilisé pour indexer une table. Dans JavaScript, tous les types non-chaîne (sauf Symbol) sont convertis en chaînes avant d'être utilisés pour indexer un objet. Par exemple, après évaluation du code suivant, la valeur de obj[1] Sera "string one" En JavaScript, mais "number one" En Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • Dans [~ # ~] js [~ # ~], les affectations sont traitées comme des expressions, mais dans Lua elles ne le sont pas. Ainsi, JS autorise les affectations dans les conditions des instructions if, while et do while, Mais Lua ne le fait pas dans if, while, et les instructions repeat until. Par exemple, if (x = 'a') {} est JS valide, mais if x = 'a' do end N'est pas Lua valide.
  • Lua contient du sucre syntaxique pour déclarer des variables de fonction à portée de bloc, des fonctions qui sont des champs et des méthodes (local function() end, function t.fieldname() end, function t:methodname() end). [~ # ~] js [~ # ~] les déclare avec un signe égal (let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).
183
outis

Quelques différences subtiles qui vous rattraperont au moins une fois:

  • Différent n'est pas orthographié ~= En Lua. Dans JS, c'est !=
  • Lua les tableaux sont basés sur 1 - leur premier index est 1 plutôt que 0.
  • Lua nécessite deux points plutôt qu'un point pour appeler des méthodes objet. Vous écrivez a:foo() au lieu de a.foo() 

 vous pouvez utiliser un point si vous le souhaitez, mais vous devez passer explicitement la variable self. a.foo(a) semble un peu lourd. Voir Programmation en Lua pour plus de détails.

12
richq

Pour être honnête, il serait plus facile d'énumérer les choses qui sont communes à Javascript et Lua que d'énumérer les différences. Ce sont deux langages de script à typage dynamique, mais c'est à peu près aussi loin que vous pouvez vraiment aller. Ils ont une syntaxe totalement différente, différents objectifs de conception d'origine, différents modes de fonctionnement (Lua est toujours compilé en bytecode et exécuté sur la machine virtuelle Lua, Javascript varie), la liste s'allonge encore et encore.

11
DaveR

Les tableaux et objets JavaScript sont plus proches que vous ne le pensez. Vous pouvez utiliser la notation de tableau pour accéder aux éléments de l'un d'eux et vous pouvez ajouter des indices non numériques aux tableaux. Les éléments de tableau individuels peuvent contenir n'importe quoi et le tableau peut être clairsemé. Ce sont des cousins ​​presque identiques.

7
Nosredna

J'ai aimé cette question et les réponses fournies. Des raisons supplémentaires pour lesquelles les deux langues me semblent plus que similaires:

Les deux affectent des fonctions aux variables, peuvent créer des fonctions à la volée et définir des fermetures.

3
WeakPointer

Du haut de ma tête

Lua ...

  1. prend en charge coroutines
  2. n'a pas de restriction à simplement chaîne/nombre comme clé pour une table. Tout fonctionne.
  3. la gestion des erreurs est quelque peu maladroite. Soit vous ne gérez rien, soit vous utilisez la méthode pcall
  4. Je pense que j'ai lu quelque chose sur les différences dans la portée lexicale et que Lua a le meilleur.
  5. Si je me souviens bien, le support des expressions régulières dans lua est limité
3
jitter

Un test révèle que le Javascript actuel renvoie également des objets, ou du moins des chaînes d'expressions logiques comme lua:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
1
Adder

Lua et JavaScript sont tous deux des langages de base prototypes.

0
Anonymous