- Lua has native 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 has many more operators, including the ternary conditional operator (?:), increment/decrement, bitwise operators, type operators (typeof and instanceof), additional assignment operators and additional comparison operators.
- In JS, the equals and not equals operators are of lower precedence than less than et al. In Lua, all comparison operators are the same precedence.
- Lua supports tail calls.
- In Lua, you can overload operators.
- In Lua, you can manipulate environments with getfenv & setfenv.
- 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 keyword for) loops over iterators and is more general.
- Integer literals in JS can be in octal.
- JS has explicit Unicode support.
- In Lua, ~ is used in place of !. (as in, if foo ~= 20 then ... end) (technically syntax, but it's easily overlooked and causes subtle bugs).
- In Lua, the not/or/and keywords are used in place of !/||/&& (also syntax but also easily forgotten).
- 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 of a.foo()