JavaScript 和 Lua 之间的细微差别 [已关闭]

2022-08-30 04:53:46

我只是喜欢JavaScript。它是如此优雅。

所以,最近我通过löve2d框架玩了Lua(很好!) - 我认为Lua也很棒。在我看来,这两种语言非常相似

有明显的区别,如

  • 语法
  • 问题域
  • 图书馆
  • 类型(一点)

但哪些更微妙?有没有一个JavaScript程序员会想当然地认为在Lua中工作只是略有不同?对于一种语言的有经验的编码人员来说,是否有任何陷阱可能不明显?

例如:在Lua中,数组和哈希不是分开的(只有表) - 在JavaScript中,它们是数字数组和哈希对象。好吧,这是更明显的区别之一。

但是,在变量范围,不变性或类似的东西方面是否存在差异?


答案 1

更多区别:

  • Lua协程具有本机支持。
    • 更新:JS现在在生成器中包含yield关键字,使其支持协程。
  • Lua 不会在任何比较运算符的类型之间进行转换。在JS中,只和不键入杂耍。===!==
  • Lua 有一个幂运算符 ();JS没有。JS 使用不同的运算符,包括三元条件运算符 ( vs ),以及从 5.3 开始的按位运算符 (, 等与元方法 )。^?:and/or&|
    • 更新:JS 现在具有幂运算符 。**
  • JS 具有递增/递减、类型运算符 ( 和 )、附加赋值运算符和其他比较运算符。typeofinstanceof
  • JS 中,、 和运算符的优先级低于 、 、 、 。在 Lua 中,所有比较运算符的优先级相同=====!=!==>>=<<=
  • Lua 支持尾部调用
  • Lua 支持分配给变量列表。虽然它在Javascript中还不是标准,但Mozilla的JS引擎(以及Opera的引擎,在某种程度上)自JS 1.7(作为Firefox 2的一部分提供)以来一直支持类似的功能,名为“解构赋值”。JS中的解构更通用,因为它可以在赋值以外的上下文中使用,例如函数定义和调用以及循环初始值设定项。一段时间以来,解构赋值一直是 ECMAScript(Javascript 背后的语言标准)的一个提议的补充。
    • 更新:解构(和解构赋值)现在是 ECMAScript 规范的一部分 - 已经在许多引擎中实现。
  • Lua 中,可以重载运算符
  • Lua 中,您可以在 Lua 5.1 或 Lua 5.2 和 5.3 中使用 getfenv 和 setfenv 操作环境。_ENV
  • JS中,所有函数都是可变参数。在 Lua 中,函数必须显式声明为可变参数
  • ForeachJS 中循环访问对象属性。Lua 中的 Foreach(使用关键字 )循环访问迭代器,并且更通用。for
    • 更新:JS现在也有迭代对象,其中许多都内置于您期望的常规数据结构中,例如.这些可以使用语法循环使用。对于常规对象,可以实现自己的迭代器函数。这使它更接近Lua。Arrayfor...of
  • JS具有全局和功能范围。Lua 具有全局和块范围。控制结构(例如,、)引入了新的ifforwhile

    • 由于作用域规则的差异,闭包对外部变量(在Lua术语中称为“upvalues”)的引用在Lua和Javascript中可能以不同的方式处理。这在 for 循环中的闭包中最常见,并且会让一些人感到惊讶。在Javascript中,循环的主体不会引入新的作用域,因此循环体中声明的任何函数都引用相同的外部变量。在 Lua 中,循环的每次迭代都会为每个循环变量创建新的局部变量。forfor

      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)
      

      因此,在单独的迭代中定义的函数对于每个引用的循环变量具有不同的上值。另请参阅Nicolas Bola对Lua中闭包实现的回答?和“循环变量上的闭包的正确语义是什么?”,以及“泛型的语义”。

      更新:JS现在有阻止范围。使用或遵循块作用域定义的变量。letconst

  • JS 中的整数文本可以是八进制的。
  • JS 具有显式 Unicode 支持,并且在内部字符串以 UTF-16 编码(因此它们是字节对的序列)。各种内置的JavaScript函数使用Unicode数据,例如()。Lua 5.3 及更高版本在字符串文本中具有 Unicode 码位转义序列(与 JavaScript 码点转义序列具有相同的语法)以及内置库,该库为 UTF-8 编码提供基本支持(例如将码点编码为 UTF-8 并将 UTF-8 解码为码位,获取字符串中的码位数, 并循环访问代码点)。Lua 中的字符串是单个字节的序列,可以包含任何编码或任意二进制数据中的文本。Lua没有任何使用Unicode数据的内置函数;的行为取决于 C 语言环境。"pâté".toUpperCase()"PÂTÉ"utf8string.upper
  • Lua 中,使用 , 、 关键字代替 JS 的 、 、 。notorand!||&&
  • Lua使用“不等于”,而JS使用.例如。~=!==if foo ~= 20 then ... end
  • Lua 5.3 及更高版本用于二进制按位 XOR,而 JS 使用 .~^
  • Lua 中,任何类型的值(和 除外)都可用于为表编制索引。在 JavaScript 中,所有非字符串类型(Symbol 除外)在用于索引对象之前都转换为字符串。例如,在评估以下代码后,的值将在 JavaScript 中,但在 Lua 中:。nilNaNobj[1]"string one""number one"obj = {}; obj[1] = "number one"; obj["1"] = "string one";
  • JS中,赋值被视为表达式,但在Lua中则不然。因此,JS 允许在 、 和 语句的条件中赋值,但 Lua 不允许在 、 和 语句中赋值。例如,是有效的 JS,但 Lua 是无效的。ifwhiledo whileifwhilerepeat untilif (x = 'a') {}if x = 'a' do end
  • Lua 具有语法糖,用于声明块范围的函数变量、作为字段的函数和方法 (, , )。JS 用等号 (, ) 声明这些。local function() endfunction t.fieldname() endfunction t:methodname() endlet funcname = function optionalFuncname() {}objectname.fieldname = function () {}

答案 2

一些微妙的差异,至少会让你发现一次:

  • 不等于 在 Lua 中拼写。在JS中,它是~=!=
  • Lua 数组基于 1 - 它们的第一个索引是 1 而不是 0。
  • Lua 需要冒号而不是句点来调用对象方法。你写而不是a:foo()a.foo()

,如果需要,可以使用句点,但必须显式传递变量。 看起来有点笨重。有关详细信息,请参阅 Lua 中的编程selfa.foo(a)