subtle differences between JavaScript and Lua

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?

46405 次浏览

老实说,列出 Javascript 和 Lua 共有的东西要比列出它们的区别容易得多。它们都是动态类型的脚本语言,但是实际上也只能到此为止了。它们有完全不同的语法,不同的原始设计目标,不同的操作模式(Lua 总是编译成字节码并在 Lua VM 上运行,Javascript 也各不相同) ,这个列表还有很多。

我第一时间想到的

卢..。

  1. 支持 协同动作
  2. 没有限制只使用字符串/数字作为表的键。
  3. 错误处理有点笨拙。要么你不处理任何东西,要么使用 呼叫方法
  4. 我想我读过一些关于词法范围的差异,Lua 有更好的一个。
  5. 如果我没记错的话,lua 中对正则表达式的支持是有限的

还有一些不同之处:

  • Lua 本地支持 协同动作
    • 更新 : JS 现在在生成器中包含屈服关键字,从而支持协程。
  • 任何比较运算符的类型之间的 Lua 不会改变信仰
  • Lua has an exponentiation operator (^); JS doesn't. JS uses different operators, including the ternary conditional operator (?: vs and/or), and, as of 5.3, bitwise operators (&, |, etc. vs. 元方法 ).
    • 更新 : JS 现在有了指数运算符 **
  • JS 具有递增/递减、类型运算符(typeofinstanceof)、额外的赋值运算符和额外的比较运算符。
  • In JS, the ==, ===, != and !== operators are of lower precedence than >, >=, <, <=. In Lua, all comparison operators are the 同样的优先级.
  • Lua 支持 跟踪电话
  • Lua 支持 赋值给变量列表。虽然它在 Javascript中还不是标准的,但 Mozilla 的 JS 引擎(在一定程度上也包括 Opera)自 JS 1.7(作为 Firefox 2的一部分)以“ 破坏性转让”的名义支持类似的功能。JS 中的解构更为普遍,因为它可以用于除赋值之外的上下文,如 function definitions & calls循环初始化器循环初始化器。一段时间以来,破坏任务一直被提议添加到 ECMAScript (Javascript 背后的语言标准)中。
    • 更新 : 解构(和解构分配)现在是 ECMAScript 规范的一部分——已经在许多引擎中实现了。
  • Lua,你可以 过载操作符
  • Lua中,可以使用 Lua 5.1中的 ABC0和 setfenvLua 5.25.3中的 _ENV操作环境。
  • JS中,所有的函数都是可变的。在 Lua中,函数必须是 explicitly declared as variadic
  • Foreach in JS loops over object properties. 前伸 in Lua (which use the keyword for) loops over iterators and is more general.
    • 更新 : JS 现在也有了 无用的东西,其中许多内置在您期望的常规数据结构中,比如 Array。这些可以用 for...of语法循环处理。对于常规对象,可以实现它们自己的迭代器函数。这样就离 Lua 更近了。
  • JS 具有全局和功能范围,Lua具有 global and block scope,控制结构(如 ifforwhile)引入新的 积木

    • 由于作用域规则的不同,在 Lua 和 Javascript中对外部变量的闭包引用(Lua 术语中称为“ upvalue”)的处理可能不同。这是最常见的经验与 for循环中的闭包,并抓住一些人的惊喜。在 Javascript中,for循环体不引入新的作用域,因此在循环体中声明的所有函数都引用 相同的外部变量。在 Lua 中,for循环的每次迭代都为每个循环变量创建新的局部变量。

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

      上述守则相当于:

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

      因此,在单独迭代中定义的函数对于每个引用的循环变量具有不同的上限值。另见尼古拉斯 · 博拉对 在 Lua 中实现闭包?和“ 循环变量上的闭包的正确语义是什么?”以及“ 泛型 for 的语义”的回答。

      更新 : JS 现在有了块作用域。用 letconst定义的变量涉及块作用域。

  • JS中的整数字面值可以是八进制。
  • JS 具有显式的 Unicode 支持,内部字符串用 UTF-16编码(因此它们是字节对序列)。各种内置的 JavaScript 函数使用 Unicode 数据,例如 "pâté".toUpperCase()("PÂTÉ")。Lua 5.3及以上版本有字符串转义序列(与 JavaScript 代码点转义序列语法相同)和内置的 utf8库,它为 UTF-8编码提供基本支持(比如将代码点编码为 UTF-8,将 UTF-8解码为代码点,获取字符串中代码点的数量,并在代码点上迭代)。Lua 中的字符串是单个字节的序列,可以包含任何编码或任意二进制数据中的文本。Lua 没有任何使用 Unicode 数据的内置函数; string.upper的行为取决于 C 语言环境。
  • In Lua, the not, or, and keywords are used in place of JS's !, ||, &&.
  • Lua 使用 ~=表示“不相等”,而 JS使用 !==
  • Lua 5.3 及以上使用 ~作为二进制位异或,而 JS使用 ^
  • Lua中,可以使用任何类型的值(nilNaN除外)来索引表。在 JavaScript中,所有非字符串类型(除了“符号”)在用于索引对象之前都被转换为字符串。例如,在对以下代码求值之后,在 JavaScript 中 obj[1]的值为 "string one",而在 Lua 中为 "number one": obj = {}; obj[1] = "number one"; obj["1"] = "string one";
  • JS中,赋值作为表达式处理,但在 Lua中不是。因此,JS 允许在 ifwhiledo while语句的条件下进行赋值,但是在 ifwhilerepeat until语句中不允许 Lua。例如,if (x = 'a') {}是有效的 JS,但 if x = 'a' do end是无效的 Lua。
  • Lua 具有用于声明块作用域函数变量、字段函数和方法(local function() endfunction t.fieldname() endfunction t:methodname() end)的语法糖。JS用一个等号(let funcname = function optionalFuncname() {}objectname.fieldname = function () {})声明它们。

JavaScript 数组和对象比你想象的更接近。您可以使用数组表示法来获取它们中任何一个的元素,并且可以向数组添加非数值索引。单个数组元素可以包含任何内容,数组可以是稀疏的。他们是近乎相同的表亲。

一些细微的差别至少会让你发现一次:

  • 不等式在 Lua 中拼写为 ~=,在 JS 中拼写为 !=
  • Lua 数组是基于1的-他们的第一个索引是1而不是0。
  • Lua 需要一个冒号而不是一个句点来调用对象方法

如果需要,可以使用句点,但必须显式地传递 self变量。a.foo(a)看起来有点麻烦。详情请参阅 Lua 编程

Lua 和 JavaScript 都是原型基础语言。

我喜欢这个问题和提供的答案。在我看来,这两种语言更为相似的另外一个原因是:

都有 将函数赋给变量, 可以动态构建函数, 定义闭包。

一个测试显示当前的 Javascript 也返回对象,或者至少像 lua 那样从逻辑表达式返回字符串:

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