I simply love JavaScript. It's so elegant.
So, recently I have played with Lua via the löve2d framework (nice!) - and I think Lua is also great. They way I see it, those two languages are very similar.
There are obvious differences, like
- syntax
- problem domain
- libraries
- types (a bit)
but which are the more subtle ones? Is there anything a JavaScript coder would take for granted that works in Lua just slightly different? Are there any pitfalls that may not be obvious to the experienced coder of one language trying the other one?
For example: in Lua, arrays and hashes are not separate (there are only tables) - in JavaScript, they are numerical Arrays and hashed Objects. Well, this is one of the more obvious differences.
But are there differences in variable scope, immutability or something like this?
-
10For those, like me, who were looking for an overall comparison and ended up here by accident, the following is a nice overview: phrogz.net/lua/LearningLua_FromJS.htmlTao– Tao2012年05月02日 10:55:29 +00:00Commented May 2, 2012 at 10:55
-
This is a three part series explaining all the differences you'll need to know to get started: oreilly.com/learning/…charAt– charAt2019年02月02日 06:36:15 +00:00Commented Feb 2, 2019 at 6:36
8 Answers 8
Some more differences:
- Lua has native support for coroutines.
- UPDATE: JS now contains the yield keyword inside generators, giving it support for coroutines.
- Lua doesn't convert between types for any comparison operators. In JS, only
===
and!==
don't type juggle. - Lua has an exponentiation operator (
^
); JS doesn't. JS uses different operators, including the ternary conditional operator (?:
vsand/or
), and, as of 5.3, bitwise operators (&
,|
, etc. vs. metamethods ).- UPDATE: JS now has the exponentiation operator
**
.
- UPDATE: JS now has the exponentiation operator
- JS has increment/decrement, type operators (
typeof
andinstanceof
), additional assignment operators and additional comparison operators. - In JS, the
==
,===
,!=
and!==
operators are of lower precedence than>
,>=
,<
,<=
. In Lua, all comparison operators are the same precedence. - Lua supports tail calls.
- UPDATE: JS now supports tail calls.
- Lua supports assignment to a list of variables. While it isn't yet standard in Javascript, Mozilla's JS engine (and Opera's, to an extent) has supported a similar feature since JS 1.7 (available as part of Firefox 2) under the name "destructuring assignment". Destructuring in JS is more general, as it can be used in contexts other than assignment, such as function definitions & calls and loop initializers. Destructuring assignment has been a proposed addition to ECMAScript (the language standard behind Javascript) for awhile.
- UPDATE: Destructuring (and destructuring assignment) is now part of the spec for ECMAScript - already implemented in many engines.
- In Lua, you can overload operators.
- In Lua, you can manipulate environments with
getfenv
andsetfenv
in Lua 5.1 or_ENV
in Lua 5.2 and 5.3. - In JS, all functions are variadic. In Lua, functions must be explicitly declared as variadic.
Foreach
in JS loops over object properties. Foreach in Lua (which use the keywordfor
) loops over iterators and is more general.- UPDATE: JS has Iterables now too, many of which are built into the regular data structures you'd expect, such as
Array
. These can be looped over with thefor...of
syntax. For regular Objects, one can implement their own iterator functions. This brings it much closer to Lua.
- UPDATE: JS has Iterables now too, many of which are built into the regular data structures you'd expect, such as
JS has global and function scope. Lua has global and block scope. Control structures (e.g.
if
,for
,while
) introduce new blocks.Due to differences in scoping rules, a closure's referencing of an outer variable (called "upvalues" in Lua parlance) may be handled differently in Lua and in Javascript. This is most commonly experienced with closures in
for
loops, and catches some people by surprise. In Javascript, the body of afor
loop doesn't introduce a new scope, so any functions declared in the loop body all reference the same outer variables. In Lua, each iteration of thefor
loop creates new local variables for each loop variable.local i='foo' for i=1,10 do -- "i" here is not the local "i" declared above ... end print(i) -- prints 'foo'
The above code is equivalent to:
local i='foo' do local _i=1 while _i<10 do local i=_i ... _i=_i+1 end end print(i)
As a consequence, functions defined in separate iterations have different upvalues for each referenced loop variable. See also Nicolas Bola's answers to Implementation of closures in Lua? and "What are the correct semantics of a closure over a loop variable?", and "The Semantics of the Generic for".
UPDATE: JS has block scope now. Variables defined with
let
orconst
respect block scope.
- Integer literals in JS can be in octal.
- JS has explicit Unicode support, and internally strings are encoded in UTF-16 (so they are sequences of pairs of bytes). Various built-in JavaScript functions use Unicode data, such as
"pâté".toUpperCase()
("PÂTÉ"
). Lua 5.3 and up have Unicode code point escape sequences in string literals (with the same syntax as JavaScript code point escape sequences) as well as the built-inutf8
library, which provides basic support for the UTF-8 encoding (such as encoding code points into UTF-8 and decoding UTF-8 into code points, getting the number of code points in a string, and iterating over code points). Strings in Lua are sequences of individual bytes and can contain text in any encoding or arbitrary binary data. Lua does not have any built-in functions that use Unicode data; the behavior ofstring.upper
depends on the C locale. - In Lua, the
not
,or
,and
keywords are used in place of JS's!
,||
,&&
. - Lua uses
~=
for "not equal", whereas JS uses!==
. For example,if foo ~= 20 then ... end
. - Lua 5.3 and up use
~
for binary bitwise XOR, whereas JS uses^
. - In Lua, any type of value (except
nil
andNaN
) can be used to index a table. In JavaScript, all non-string types (except Symbol) are converted to strings before being used to index an object. For example, after evaluation of the following code, the value ofobj[1]
will be"string one"
in JavaScript, but"number one"
in Lua:obj = {}; obj[1] = "number one"; obj["1"] = "string one";
. - In JS, assignments are treated as expressions, but in Lua they are not. Thus, JS allows assignments in conditions of
if
,while
, anddo while
statements, but Lua does not inif
,while
, andrepeat until
statements. For example,if (x = 'a') {}
is valid JS, butif x = 'a' do end
is invalid Lua. - Lua has syntactic sugar for declaring block-scoped function variables, functions that are fields, and methods (
local function() end
,function t.fieldname() end
,function t:methodname() end
). JS declares these with an equals sign (let funcname = function optionalFuncname() {}
,objectname.fieldname = function () {}
).
-
6in Lua, logical operators (and, or) do return one of the arguments. all functions can be called with any number of parameters; but are adjusted to the needed number (unless you use the ... 'extra args')Javier– Javier2009年06月20日 23:05:29 +00:00Commented Jun 20, 2009 at 23:05
-
1@RCIX: see luaconf.h (and in Lua 5.2, also lparser.c and llimits.h). Max local values/function = 200 in Lua 5.1 and Lua 5.2. Max upvalues/function = 60 in Lua 5.1, 255 in Lua 5.2 (and this count includes also upvalues "inherited by" closures created inside the function).dubiousjim– dubiousjim2012年06月01日 18:54:21 +00:00Commented Jun 1, 2012 at 18:54
-
9I think you can add 1-based arrays to the list, it can be pretty annoying when you are not used to it.Yann– Yann2014年08月05日 13:03:50 +00:00Commented Aug 5, 2014 at 13:03
-
2Only nil and false are falsy in Lua - so, for example, 0 is truthy in Lua but not in js. About Unicode support: Lua 5.3 adds some explicit UTF-8 support, and older Lua versions are friendly to UTF-8 buffers held in strings (eg you can use Unicode in string search patterns). Js support of UTF-8 is not perfect as V8 internally uses an old 16-bit representation, so your unicode strings may end up with (surprise!) surrogate pairs that wouldn't be needed in good ol' UTF-8 (and won't happen in Lua).Tyler– Tyler2015年01月07日 19:05:54 +00:00Commented Jan 7, 2015 at 19:05
-
5I loved this list, but I don't see how
~=
can provoke subtle bugs. It can provoke syntax errors, but they are not at all subtle.kikito– kikito2015年01月25日 20:27:01 +00:00Commented Jan 25, 2015 at 20:27
A couple of subtle differences that will catch you out at least once:
- Not equal is spelled
~=
in Lua. In JS it is!=
- Lua arrays are 1-based - their first index is 1 rather than 0.
- Lua requires a colon rather than a period to call object methods. You write
a:foo()
instead ofa.foo()
†
† you can use a period if you want, but have to pass the self
variable explicitly. a.foo(a)
looks a bit cumbersome. See Programming in Lua for details.
-
10using the
†
for the annotation makes it seem likea.foo()
has died xDDarkWiiPlayer– DarkWiiPlayer2019年01月31日 08:29:08 +00:00Commented Jan 31, 2019 at 8:29 -
- In Lua you can skip the parentheses when you call a function with a single argument. - The difference between calling with period and colon is exactly the extra dot that is for passing self as the first argument which makes it a call to an instance method rather than a statically scoped function.Zsolt– Zsolt2024年02月17日 22:06:56 +00:00Commented Feb 17, 2024 at 22:06
To be honest it would be easier to list the things which are common to Javascript and Lua than to list the differences. They are both dynamically-typed scripting languages, but that's about as far as you can go really. They have totally different syntax, different original design goals, different modes of operation (Lua is always compiled to bytecode and run on the Lua VM, Javascript varies), the list goes on and on.
-
8absolutely. the very different goals include a high priority for having a clean language. Javascript has a lot of historical baggage, Lua continually sheds anything that's undesired.Javier– Javier2009年06月20日 23:07:12 +00:00Commented Jun 20, 2009 at 23:07
-
3+1. I don't even see how they're similar at all, except for the fact that they're both used for scripting (which is too obvious).Sasha Chedygov– Sasha Chedygov2009年06月21日 01:59:18 +00:00Commented Jun 21, 2009 at 1:59
-
15-1 (if I could) They are very similar on the language design front. Lua simply has more features and is smaller (also faster?). I think you confuse language design with implementation choices.jpc– jpc2011年04月21日 10:36:32 +00:00Commented Apr 21, 2011 at 10:36
-
1Yeah, they are both prototype OOP (even if it's not explicitly stated using keyword
prototype
or naming objects objects, despite the fact that that's exactly what lua tables are), with functions as first-class citizen despite not being functional in the traditional sense (immutablility, declarative development etc.),Bojan Markovic– Bojan Markovic2016年01月13日 13:44:52 +00:00Commented Jan 13, 2016 at 13:44 -
5Sure, there are syntactic differences and if you look at it superficially, you may conclude the languages are different. However in having exactly the same main data type (object/table) and the same way of implementing classes and inherritance (something that very few other languages share) makes them amazingly close in spirit. The design of non-trivial JS program would be pretty much the same as that of a Lua one.Alex Gian– Alex Gian2017年02月10日 07:23:42 +00:00Commented Feb 10, 2017 at 7:23
JavaScript arrays and objects are closer than you might think. You can use array notation to get at the elements of either of them, and you can add non-numeric indices to arrays. Individual array elements can hold anything, and the array can be sparse. They are nearly identical cousins.
-
1Can one have identical cousins?jameshfisher– jameshfisher2011年06月22日 15:52:05 +00:00Commented Jun 22, 2011 at 15:52
-
They're the same data structure, the only difference is the type descriptor so you can tell them apart.Lilith River– Lilith River2011年08月21日 19:41:19 +00:00Commented Aug 21, 2011 at 19:41
-
5A more accurate statement would be: Arrays are Objects with special behavior of their "length" member.tzenes– tzenes2011年09月14日 17:27:10 +00:00Commented Sep 14, 2011 at 17:27
-
1@eegg: sure, Cathy and Patty.outis– outis2012年06月02日 07:31:17 +00:00Commented Jun 2, 2012 at 7:31
I liked this question and the answers provided. Additional reasons the two languages seem more alike than not to me:
Both assign functions to variables, can build functions on the fly, and define closures.
-
They started out different, but are gradually converging.nomad– nomad2021年05月04日 04:26:23 +00:00Commented May 4, 2021 at 4:26
Off the top of my head
Lua ...
- supports coroutines
- has no restriction to just string/number as key for a table. Everything works.
- the error handling is somewhat clumsy. Either you don't handle anything or use the pcall method
- I think I read something about differences in the lexical scope and that Lua has the better one.
- If I recall correctly regular expression support in lua is limited
-
Lua does have lexical scope. JavaScript only has function scope. well, in Mozilla and Rhino yo can now use 'let' instead of 'var' and get proper lexical scope; but it's not portable yet.Javier– Javier2009年06月20日 23:08:25 +00:00Commented Jun 20, 2009 at 23:08
-
1Lua's standard string library includes limited pattern matching functions; but there's also LPEG (also a library), which gives a much more powerful matching system, easily usable for a full grammar.Javier– Javier2009年06月20日 23:10:22 +00:00Commented Jun 20, 2009 at 23:10
-
I stated that LUA has the "better" lexical scope then javascript not that it hasn't any.jitter– jitter2009年06月20日 23:50:27 +00:00Commented Jun 20, 2009 at 23:50
-
1LPEG is an additional library which means core regex support is limited to mejitter– jitter2009年06月20日 23:51:59 +00:00Commented Jun 20, 2009 at 23:51
-
there is somewhat of a restriction between string keys and number keys, using both in the same table gets messy very fast, as # returns table length, not by the amount of numbered indexes, which will conflict with any dictionary entry (indexing nil after enumerated table indexes)Weeve Ferrelaine– Weeve Ferrelaine2014年01月01日 19:37:03 +00:00Commented Jan 1, 2014 at 19:37
Lua and JavaScript are both prototype base languages.
-
1This is the obvious similarity between the two languages, this and their use of tables/hashes as the main data type. If you were to develop a Javascript program idiomatically, you would take pretty much the same approach as you would in Lua. You would not do the same in a ny other language (unless it's a language based on protype inherittance and tables). This is a huge similarity. The rest, details about minor syntax and so on are pretty pedantic in comparison.Alex Gian– Alex Gian2017年01月07日 01:15:55 +00:00Commented Jan 7, 2017 at 1:15
-
1The important differences are that Jaavscript does not support coroutines, is not very tightly coupled with C, and is not really suitable as an embedded language. (How many microcontrollers are programmed in Javascript?) Javascript is also much messier, with tons of legacy gotchas and WATs (destroyallsoftware.com/talks/wat) - from 1:40. Lua has had a pretty Spartan discipline imposed. Javascript, of course, is very strong in the browser.Alex Gian– Alex Gian2017年01月07日 01:30:10 +00:00Commented Jan 7, 2017 at 1:30
A test reveals that current Javascript also returns objects, or at least strings from logic expressions like lua does:
function nix(){
alert(arguments[0]||"0");
}
nix();