différences subtiles entre JavaScript et Lua [fermé]

121

J'adore tout 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 (sympa!) - et je pense que Lua est également génial. Selon moi, ces deux langues sont très similaires.

Il existe des différences évidentes, comme

  • syntaxe
  • domaine de problème
  • 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 légèrement différemment dans Lua? Y a-t-il des écueils qui ne sont peut-être pas é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?

stefs
la source
8
Pour ceux qui, comme moi, cherchaient une comparaison globale et se sont retrouvés ici par accident, voici un bel aperçu: phrogz.net/lua/LearningLua_FromJS.html
Tao
Ceci est une série de trois partie expliquant toutes les différences que vous devez savoir pour commencer: oreilly.com/learning/...
charAt

Réponses:

189

Quelques autres différences:

  • Lua a un support natif pour les coroutines .
    • MISE À JOUR : JS contient maintenant le mot-clé yield dans les générateurs, ce qui lui permet de prendre en charge les coroutines.
  • Lua ne convertit pas entre les types pour les opérateurs de comparaison. Dans JS, seulement ===et !==ne tapez pas jongler.
  • Lua a un opérateur d'exponentiation ( ^); JS ne le fait pas. JS utilise des opérateurs différents, y compris l'opérateur conditionnel ternaire ( ?:vs and/or), et, de 5.3, les opérateurs ( au niveau du bit &, |etc. contre métaméthodes ).
    • UPDATE : JS a maintenant l'opérateur d'exponentiation **.
  • JS a incrémentation / décrémentation, des opérateurs de type ( typeofet instanceof), des opérateurs d'affectation supplémentaires et des opérateurs de comparaison supplémentaires.
  • Dans JS , les ==, ===, !=et les !==opérateurs sont de priorité inférieur >, >=, <, <=. Dans Lua, tous les opérateurs de comparaison ont la même priorité .
  • Lua prend en charge les appels de queue .
  • Lua prend en charge l' affectation à une liste de variables . Bien qu'il ne soit pas encore standard en Javascript , le moteur JS de Mozilla (et d'Opera, dans une certaine mesure) a pris en charge une fonctionnalité similaire depuis JS 1.7 (disponible dans Firefox 2) sous le nom de « affectation de déstructuration ». 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 les définitions et les appels de fonctions et les initialiseurs de boucle . L'affectation de déstructuration a été un ajout proposé à ECMAScript (le langage standard derrière Javascript) pendant un certain temps.
    • MISE À JOUR : La destruction (et l'affectation de déstructuration) fait maintenant partie de la spécification d'ECMAScript - déjà implémentée dans de nombreux moteurs.
  • Dans Lua , vous pouvez surcharger les opérateurs .
  • Dans Lua , vous pouvez manipuler des environnements avec getfenvetsetfenv dans Lua 5.1 ou _ENVdans Lua 5.2 et 5.3 .
  • Dans JS , toutes les fonctions sont variadiques. En Lua , les fonctions doivent être explicitement déclarées comme variadiques .
  • Foreachdans JS boucle sur les propriétés de l'objet. Foreach dans Lua (qui utilise le mot-clé for) boucle sur les itérateurs et est plus général.
    • MISE À JOUR : JS a maintenant aussi des Iterables , dont beaucoup sont intégrés dans les structures de données régulières que vous attendez, telles que Array. Ceux-ci peuvent être bouclés avec la for...ofsyntaxe. Pour les objets normaux, 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 une portée globale et de bloc . Les structures de contrôle (par exemple if, for, while) introduisent de nouveaux blocs .

    • En raison des différences dans les règles de cadrage, le référencement d'une variable externe (appelée "upvalues" en langage Lua) peut être géré différemment en Lua et en Javascript . Cela se produit le plus souvent avec des fermetures en forboucle , et prend certaines personnes par surprise. En Javascript , le corps d'une forboucle n'introduit pas de nouvelle portée, donc toutes les fonctions déclarées dans le corps de la boucle font toutes référence aux mêmes variables externes . Dans Lua, chaque itération de la forboucle 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)

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

      MISE À JOUR : JS a maintenant une portée de bloc. Variables définies avec letou constrespectant la portée du bloc.

  • Les littéraux entiers dans JS peuvent être en octal.
  • JS prend en charge explicitement Unicode et les chaînes en interne sont codées en UTF-16 (ce sont donc 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 versions ultérieures ont des séquences d'échappement de points de code Unicode dans des chaînes littérales (avec la même syntaxe que les séquences d'échappement de points de code JavaScript) ainsi que la utf8bibliothèque intégrée, qui fournit un support de base pour l' encodage UTF-8(comme le codage de points de code en UTF-8 et le décodage de 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 encodage 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.upperdépend de la locale C.
  • Dans Lua , le not, or, les andmots clés sont utilisés à la place de JS d » !, ||, &&.
  • Lua utilise ~=pour "pas égal", alors que JS utilise !==. Par exemple if foo ~= 20 then ... end,.
  • Lua 5.3 et versions ultérieures utilisent ~pour XOR binaire bit à bit, alors que JS utilise ^.
  • En Lua , tout type de valeur (sauf nilet NaN) peut être utilisé pour indexer une table. En JavaScript , tous les types non-chaîne (à l'exception de Symbol) sont convertis en chaînes avant d'être utilisés pour indexer un objet. Par exemple, après évaluation du code ci - dessous, la valeur obj[1]sera "string one"en JavaScript, mais "number one"dans Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • Dans JS , les affectations sont traitées comme des expressions, mais en Lua elles ne le sont pas. Ainsi, JS permet des missions dans des conditions de if, whileet des do whiledéclarations, mais ne pas Lua if, whileet des repeat untildéclarations. Par exemple, if (x = 'a') {}est un JS valide, mais if x = 'a' do endest un Lua non valide.
  • Lua a sucre syntaxique pour déclarer des variables de la fonction bloc-scope, 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 () {}).
hors
la source
6
en Lua, les opérateurs logiques (et, ou) renvoient l'un des arguments. toutes les fonctions peuvent être appelées avec n'importe quel nombre de paramètres; mais sont ajustés au nombre nécessaire (sauf si vous utilisez le ... 'extra args')
Javier
1
@RCIX: voir luaconf.h (et dans Lua 5.2, aussi lparser.c et llimits.h). Valeurs / fonction locales maximales = 200 dans Lua 5.1 et Lua 5.2. Max upvalues ​​/ function = 60 dans Lua 5.1, 255 dans Lua 5.2 (et ce décompte inclut également les upvalues ​​"héritées par" des fermetures créées à l'intérieur de la fonction).
dubiousjim
8
Je pense que vous pouvez ajouter des tableaux basés sur 1 à la liste, cela peut être assez ennuyeux lorsque vous n'y êtes pas habitué.
Yann
2
Seuls nil et false sont faux en Lua - ainsi, par exemple, 0 est vrai en Lua mais pas en js. À propos du support Unicode: Lua 5.3 ajoute un support UTF-8 explicite, et les anciennes versions de Lua sont compatibles avec les tampons UTF-8 contenus dans des chaînes (par exemple, vous pouvez utiliser Unicode dans les modèles de recherche de chaînes). Le support Js de UTF-8 n'est pas parfait car V8 utilise en interne une ancienne représentation 16 bits, donc vos chaînes Unicode peuvent se retrouver avec des paires de substitution (surprise!) Qui ne seraient pas nécessaires dans le bon vieux UTF-8 (et ont gagné ça n'arrive pas à Lua).
Tyler
4
J'ai adoré cette liste, mais je ne vois pas comment ~=provoquer des bugs subtils . Cela peut provoquer des erreurs de syntaxe , mais elles ne sont pas du tout subtiles.
kikito
12

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

  • Pas égal est orthographié ~=en Lua. Dans JS c'est!=
  • Les tableaux Lua sont basés sur 1 - leur premier index est 1 plutôt que 0.
  • Lua nécessite un 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 devez passer la selfvariable explicitement. a.foo(a)semble un peu encombrant. Voir Programmation en Lua pour plus de détails.

richq
la source
5
l'utilisation du pour l'annotation donne l'impression d'être a.foo()mort xD
DarkWiiPlayer
11

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

DaveR
la source
8
absolument. les objectifs très différents incluent une priorité élevée pour avoir un langage clair. Javascript a beaucoup de bagages historiques, Lua jette continuellement tout ce qui n'est pas désiré.
Javier
3
+1. Je ne vois même pas en quoi ils se ressemblent du tout, à part le fait qu'ils sont tous deux utilisés pour les scripts (ce qui est trop évident).
Sasha Chedygov
13
-1 (si je pouvais) Ils sont très similaires sur le plan de la conception du langage. Lua a simplement plus de fonctionnalités et est plus petit (également plus rapide?). Je pense que vous confondez la conception du langage avec les choix d'implémentation.
jpc
Oui, ce sont tous les deux des prototypes de POO (même si ce n'est pas explicitement indiqué à l'aide de mots prototype- clés ou de nommer des objets, malgré le fait que c'est exactement ce que sont les tables lua), avec des fonctions de citoyen de première classe bien qu'elles ne soient pas fonctionnelles au sens traditionnel (immutablilité , développement déclaratif etc.),
Bojan Markovic
2
Bien sûr, il existe des différences syntaxiques et si vous les regardez superficiellement, vous pouvez conclure que les langues sont différentes. Cependant, avoir exactement le même type de données principal (objet / table) et la même façon d'implémenter les classes et l'héritage (quelque chose que très peu d'autres langues partagent) les rend étonnamment proches dans l'esprit. La conception d'un programme JS non trivial serait à peu près la même que celle d'un programme Lua.
Alex Gian
7

Les tableaux et objets JavaScript sont plus proches que vous ne le pensez. Vous pouvez utiliser la notation de tableau pour obtenir les éléments de l'un ou l'autre d'entre 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 fragmenté. Ce sont des cousins ​​presque identiques.

Nosredna
la source
1
Peut-on avoir des cousins ​​identiques?
jameshfisher
Ce sont la même structure de données, la seule différence est le descripteur de type afin que vous puissiez les distinguer.
Lilith River
5
Une déclaration plus précise serait: Les tableaux sont des objets avec un comportement spécial de leur membre "longueur".
tzenes le
@eegg: bien sûr, Cathy et Patty .
sortie le
3

Du haut de ma tête

Lua ...

  1. prend en charge les coroutines
  2. n'a aucune restriction à la simple 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 avoir lu quelque chose sur les différences de portée lexicale et que Lua a la meilleure.
  5. Si je me souviens bien, le support des expressions régulières dans lua est limité
trembler
la source
Lua n'ont une portée lexicale. JavaScript n'a qu'une portée de fonction. eh bien, dans Mozilla et Rhino, vous pouvez maintenant utiliser «let» au lieu de «var» et obtenir une portée lexicale appropriée; mais ce n'est pas encore portable.
Javier
1
La bibliothèque de chaînes standard de Lua comprend des fonctions de correspondance de modèles limitées; mais il y a aussi LPEG (également une bibliothèque), qui donne un système de correspondance beaucoup plus puissant, facilement utilisable pour une grammaire complète.
Javier
J'ai déclaré que LUA avait la «meilleure» portée lexicale que javascript, pas qu'elle n'en a pas.
jitter
1
LPEG est une bibliothèque supplémentaire, ce qui signifie que le support des regex de base est limité à moi
jitter
il y a une sorte de restriction entre les clés de chaîne et les touches numériques, l'utilisation des deux dans la même table devient très vite désordonnée, car # renvoie la longueur de la table, pas par le nombre d'index numérotés, qui entreront en conflit avec n'importe quelle entrée de dictionnaire (indexer nil après énumération index des tables)
Weeve Ferrelaine
3

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

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

WeakPointer
la source
1

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


la source
1
C'est la similitude évidente entre les deux langages, ceci et leur utilisation des tables / hachages comme type de données principal. Si vous deviez développer un programme Javascript de manière idiomatique, vous adopteriez à peu près la même approche que vous le feriez dans Lua. Vous ne feriez pas la même chose dans une autre langue (sauf si c'est une langue basée sur l'héritage de protype et les tables). C'est une énorme similitude. Le reste, les détails sur la syntaxe mineure et ainsi de suite sont assez pédants en comparaison.
Alex Gian
1
Les différences importantes sont que Jaavscript ne prend pas en charge les coroutines, n'est pas très étroitement couplé avec C et n'est pas vraiment adapté en tant que langage embarqué. (Combien de microcontrôleurs sont programmés en Javascript?) Javascript est également beaucoup plus compliqué, avec des tonnes de pièges hérités et de WATs ( destroyallsoftware.com/talks/wat ) - à partir de 1:40. Lua s'est vu imposer une discipline assez spartiate. Javascript, bien sûr, est très puissant dans le navigateur.
Alex Gian
1

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

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Additionneur
la source