diferencias sutiles entre JavaScript y Lua [cerrado]

121

Simplemente me encanta JavaScript. Es muy elegante (imagina el sonido tranquilo del fanboy enamorado suspirando en el fondo).

Entonces, recientemente he jugado con Lua a través del marco löve2d (¡genial!), Y creo que Lua también es genial. A mi modo de ver, esos dos idiomas son muy similares.

Hay diferencias obvias, como

  • sintaxis
  • dominio problemático
  • bibliotecas
  • tipos (un poco)

pero cuales son los más sutiles? ¿Hay algo que un codificador de JavaScript daría por sentado que funciona en Lua solo un poco diferente? ¿Hay alguna dificultad que puede no ser obvia para el codificador experimentado de un idioma que prueba el otro?

Por ejemplo: en Lua, las matrices y los hashes no están separados (solo hay tablas); en JavaScript, son matrices numéricas y objetos hash. Bueno, esta es una de las diferencias más obvias.

Pero, ¿hay diferencias en el alcance variable, la inmutabilidad o algo así?

stefs
fuente
8
Para aquellos, como yo, que buscaban una comparación general y terminaron aquí por accidente, la siguiente es una buena descripción general: phrogz.net/lua/LearningLua_FromJS.html
Tao
Esta es una serie de tres partes que explica todas las diferencias que necesitará saber para comenzar: oreilly.com/learning/…
charAt

Respuestas:

189

Algunas diferencias más:

  • Lua tiene soporte nativo para las corutinas .
    • ACTUALIZACIÓN : JS ahora contiene la palabra clave de rendimiento dentro de los generadores, lo que le da soporte para las rutinas.
  • Lua no convierte entre tipos para ningún operador de comparación. En JS, solo ===y !==no escriba malabares.
  • Lua tiene un operador de exponenciación ( ^); JS no lo hace. JS utiliza diferentes operadores, incluyendo el operador condicional ternario ( ?:vs and/or), y, a partir de 5.3, operadores bit a bit ( &, |, etc. vs. metamétodos ).
    • ACTUALIZACIÓN : JS ahora tiene el operador de exponenciación **.
  • JS tiene incrementos / decrementos, operadores de tipo ( typeofy instanceof), operadores de asignación adicionales y operadores de comparación adicionales.
  • En JS , los ==, ===, !=y !==operadores son de menor precedencia que >, >=, <, <=. En Lua, todos los operadores de comparación tienen la misma precedencia .
  • Lua admite llamadas de cola .
  • Lua admite la asignación a una lista de variables . Si bien aún no es estándar en Javascript , el motor JS de Mozilla (y el de Opera, hasta cierto punto) ha admitido una característica similar desde JS 1.7 (disponible como parte de Firefox 2) bajo el nombre de " asignación de desestructuración ". La desestructuración en JS es más general, ya que se puede usar en contextos distintos de la asignación, como definiciones de funciones y llamadas e inicializadores de bucle . La asignación de desestructuración ha sido una adición propuesta a ECMAScript (el estándar de lenguaje detrás de Javascript) por un tiempo.
    • ACTUALIZACIÓN : La desestructuración (y la asignación de desestructuración) ahora es parte de la especificación para ECMAScript, ya implementada en muchos motores.
  • En Lua , puede sobrecargar a los operadores .
  • En Lua , puede manipular entornos con getfenvysetfenv en Lua 5.1 o _ENVen Lua 5.2 y 5.3 .
  • En JS , todas las funciones son variadas. En Lua , las funciones deben declararse explícitamente como variables .
  • Foreachen JS recorre las propiedades del objeto. Foreach en Lua (que usa la palabra clave for) recorre los iteradores y es más general.
    • ACTUALIZACIÓN : JS también tiene Iterables , muchos de los cuales están integrados en las estructuras de datos normales que esperaría, como Array. Estos se pueden enlazar con la for...ofsintaxis. Para objetos normales, uno puede implementar sus propias funciones de iterador. Esto lo acerca mucho más a Lua.
  • JS tiene alcance global y funcional. Lua tiene alcance global y de bloque . Las estructuras de control (p if. Ej . for, while) Introducen nuevos bloques .

    • Debido a las diferencias en las reglas de alcance, la referencia de cierre de una variable externa (llamada "valores superiores" en lenguaje Lua) puede manejarse de manera diferente en Lua y en Javascript . Esto se experimenta con mayor frecuencia con los cierres en forbucles , y sorprende a algunas personas. En Javascript , el cuerpo de un forbucle no introduce un nuevo alcance, por lo que todas las funciones declaradas en el cuerpo del bucle hacen referencia a las mismas variables externas . En Lua, cada iteración del forciclo crea nuevas variables locales para cada variable del ciclo.

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

      El código anterior es equivalente a:

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

      Como consecuencia, las funciones definidas en iteraciones separadas tienen valores ascendentes diferentes para cada variable de bucle referenciada. Ver también las respuestas de Nicolas Bola a la implementación de cierres en Lua? y " ¿Cuál es la semántica correcta de un cierre sobre una variable de bucle? " y " La semántica de lo genérico para ".

      ACTUALIZACIÓN : JS tiene alcance de bloque ahora. Variables definidas con leto constrespetan el alcance del bloque.

  • Los literales enteros en JS pueden estar en octal.
  • JS tiene soporte explícito de Unicode, y las cadenas internas están codificadas en UTF-16 (por lo que son secuencias de pares de bytes). Varias funciones de JavaScript incorporadas utilizan datos Unicode, como "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 y versiones posteriores tienen secuencias de escape de puntos de código Unicode en literales de cadena (con la misma sintaxis que las secuencias de escape de puntos de código JavaScript), así como la utf8biblioteca incorporada , que proporciona soporte básico para la codificación UTF-8(como codificar puntos de código en UTF-8 y decodificar UTF-8 en puntos de código, obtener el número de puntos de código en una cadena e iterar sobre puntos de código). Las cadenas en Lua son secuencias de bytes individuales y pueden contener texto en cualquier codificación o datos binarios arbitrarios. Lua no tiene ninguna función incorporada que use datos Unicode; el comportamiento de string.upperdepende de la configuración regional C.
  • En Lua , la not, or, andpalabras clave se utilizan en lugar de JS s' !, ||, &&.
  • Lua usa ~=para "no igual", mientras que JS usa !==. Por ejemplo, if foo ~= 20 then ... end.
  • Uso de Lua 5.3 y versiones posteriores ~para XOR bitinario binario, mientras que JS usa ^.
  • En Lua , cualquier tipo de valor (excepto nily NaN) se puede usar para indexar una tabla. En JavaScript , todos los tipos que no son cadenas (excepto el Símbolo) se convierten en cadenas antes de usarse para indexar un objeto. Por ejemplo, después de la evaluación del código siguiente, el valor de obj[1]será "string one"en JavaScript, pero "number one"en Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • En JS , las asignaciones se tratan como expresiones, pero en Lua no lo son. Por lo tanto, JS permite asignaciones en condiciones de if, whiley do whiledeclaraciones, pero no lo hace en Lua if, whiley repeat untildeclaraciones. Por ejemplo, if (x = 'a') {}es válido JS, pero if x = 'a' do endno es válido Lua.
  • Lua tiene azúcar sintáctico para la declaración de variables de la función de bloque de ámbito, funciones que son campos, y métodos ( local function() end, function t.fieldname() end, function t:methodname() end). JS declara estos con un signo igual ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).
outis
fuente
66
en Lua, los operadores lógicos (y, o) devuelven uno de los argumentos. todas las funciones se pueden llamar con cualquier número de parámetros; pero se ajustan al número necesario (a menos que use el ... 'args extra')
Javier
1
@RCIX: ver luaconf.h (y en Lua 5.2, también lparser.c y llimits.h). Valores locales máximos / función = 200 en Lua 5.1 y Lua 5.2. Valores máximos / función = 60 en Lua 5.1, 255 en Lua 5.2 (y este recuento incluye también valores ascendentes "heredados por" cierres creados dentro de la función).
dubiousjim 01 de
8
Creo que puede agregar matrices basadas en 1 a la lista, puede ser bastante molesto cuando no está acostumbrado.
Yann
2
Solo nil y false son falsos en Lua; por lo tanto, 0 es verdadero en Lua pero no en js. Acerca del soporte de Unicode: Lua 5.3 agrega un poco de soporte explícito de UTF-8, y las versiones anteriores de Lua son compatibles con los buffers UTF-8 que se encuentran en cadenas (por ejemplo, puede usar Unicode en los patrones de búsqueda de cadenas). El soporte de JT de UTF-8 no es perfecto ya que V8 usa internamente una antigua representación de 16 bits, por lo que sus cadenas unicode pueden terminar con (¡sorpresa!) Pares sustitutos que no serían necesarios en un buen UTF-8 (y ganó Sucede en Lua).
Tyler
44
Me encantó esta lista, pero no veo cómo ~=puede provocar errores sutiles . Puede provocar errores de sintaxis , pero no son nada sutiles.
kikito
12

Un par de diferencias sutiles que te atraparán al menos una vez:

  • No igual se deletrea ~=en Lua. En JS es!=
  • Las matrices Lua están basadas en 1 : su primer índice es 1 en lugar de 0.
  • Lua requiere dos puntos en lugar de un punto para llamar a métodos de objeto. Escribes en a:foo()lugar de a.foo()

puede usar un punto si lo desea, pero tiene que pasar la selfvariable explícitamente. a.foo(a)se ve un poco engorroso. Vea Programación en Lua para más detalles.

richq
fuente
55
usar el para la anotación hace que parezca que a.foo()ha muerto xD
DarkWiiPlayer
11

Para ser sincero, sería más fácil enumerar las cosas que son comunes a Javascript y Lua que enumerar las diferencias. Ambos son lenguajes de secuencias de comandos de tipo dinámico, pero eso es lo más lejos que puedes llegar realmente. Tienen una sintaxis totalmente diferente, diferentes objetivos de diseño originales, diferentes modos de operación (Lua siempre se compila para bytecode y se ejecuta en Lua VM, Javascript varía), la lista sigue y sigue.

DaveR
fuente
8
absolutamente. Los objetivos muy diferentes incluyen una alta prioridad para tener un lenguaje limpio. Javascript tiene una gran cantidad de equipaje histórico, Lua continuamente arroja todo lo que no desea.
Javier
3
+1. Ni siquiera veo cómo son similares en absoluto, excepto por el hecho de que ambos se usan para crear secuencias de comandos (lo cual es demasiado obvio).
Sasha Chedygov
13
-1 (si pudiera) Son muy similares en el frente del diseño del lenguaje. Lua simplemente tiene más funciones y es más pequeño (¿también más rápido?). Creo que confunde el diseño del lenguaje con las opciones de implementación.
jpc
Sí, ambos son prototipos de OOP (incluso si no se establece explícitamente usando palabras clave prototypeo nombrando objetos de objetos, a pesar de que eso es exactamente lo que son las tablas lua), con funciones como ciudadanos de primera clase a pesar de no ser funcionales en el sentido tradicional (inmutabilidad , desarrollo declarativo, etc.),
Bojan Markovic
2
Claro, hay diferencias sintácticas y si lo miras superficialmente, puedes concluir que los idiomas son diferentes. Sin embargo, al tener exactamente el mismo tipo de datos principal (objeto / tabla) y la misma forma de implementar clases y herencia (algo que muy pocos idiomas comparten) los hace increíblemente cercanos en espíritu. El diseño del programa JS no trivial sería prácticamente el mismo que el de un programa Lua.
Alex Gian
7

Las matrices y objetos de JavaScript están más cerca de lo que piensas. Puede usar la notación de matriz para obtener los elementos de cualquiera de ellos, y puede agregar índices no numéricos a las matrices. Los elementos de matriz individuales pueden contener cualquier cosa, y la matriz puede ser escasa. Son primos casi idénticos.

Nosredna
fuente
1
¿Se pueden tener primos idénticos?
jameshfisher
Son la misma estructura de datos, la única diferencia es el descriptor de tipo para que pueda distinguirlos.
Lilith River
55
Una declaración más precisa sería: Las matrices son objetos con un comportamiento especial de su miembro de "longitud".
tzenes
@eegg: claro, Cathy y Patty .
outis
3

La parte superior de mi cabeza

Lua ...

  1. soporta corutinas
  2. no tiene restricción para solo cadena / número como clave para una tabla. Todo funciona.
  3. El manejo de errores es algo torpe. O no manejas nada o usas el método pcall
  4. Creo que leí algo sobre las diferencias en el ámbito léxico y que Lua tiene el mejor.
  5. Si recuerdo correctamente, el soporte de expresiones regulares en lua es limitado
estar nervioso
fuente
Lua hace tener ámbito léxico. JavaScript solo tiene alcance de función. bueno, en Mozilla y Rhino ahora puedes usar 'let' en lugar de 'var' y obtener el alcance léxico adecuado; pero aún no es portátil.
Javier
1
La biblioteca de cadenas estándar de Lua incluye funciones limitadas de coincidencia de patrones; pero también hay LPEG (también una biblioteca), que proporciona un sistema de correspondencia mucho más potente, fácilmente utilizable para una gramática completa.
Javier
Dije que LUA tiene el "mejor" alcance léxico que javascript, no que no tiene ninguno.
jitter
1
LPEG es una biblioteca adicional que significa el apoyo básico de expresiones regulares se limita a mí
jitter
existe una cierta restricción entre las teclas de cadena y las teclas numéricas, usar ambas en la misma tabla se vuelve desordenado muy rápido, ya que # devuelve la longitud de la tabla, no por la cantidad de índices numerados, lo que entrará en conflicto con cualquier entrada del diccionario (indexación nula después de enumerar índices de la tabla)
Weeve Ferrelaine 01 de
3

Me gustó esta pregunta y las respuestas proporcionadas. Razones adicionales que los dos idiomas me parecen más parecidos que a mí:

Ambos asignan funciones a variables, pueden construir funciones sobre la marcha y definir cierres.

WeakPointer
fuente
1

Lua y JavaScript son ambos lenguajes base prototipo.


fuente
1
Esta es la similitud obvia entre los dos idiomas, esto y su uso de tablas / hashes como el tipo de datos principal. Si desarrollara un programa Javascript de forma idiomática, adoptaría el mismo enfoque que utilizaría en Lua. No haría lo mismo en ningún otro idioma (a menos que sea un idioma basado en la herencia de prototipos y tablas). Esta es una gran similitud. El resto, los detalles sobre sintaxis menor, etc., son bastante pedantes en comparación.
Alex Gian
1
Las diferencias importantes son que Jaavscript no admite corutinas, no está muy estrechamente acoplado con C y no es realmente adecuado como lenguaje incrustado. (¿Cuántos microcontroladores están programados en Javascript?) Javascript también es mucho más desordenado, con toneladas de gotchas y WAT heredados ( destroyallsoftware.com/talks/wat ) - desde 1:40. A Lua se le ha impuesto una disciplina espartana bonita. Javascript, por supuesto, es muy fuerte en el navegador.
Alex Gian
1

Una prueba revela que Javascript actual también devuelve objetos, o al menos cadenas de expresiones lógicas como lo hace lua:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Sumador
fuente