我只是喜欢JavaScript.这是如此优雅(想象一下在背景中叹息的爱情狂热的声音).
所以,最近我通过löve2d框架玩了Lua (很好!) - 我认为Lua也很棒.他们看待它,这两种语言非常相似.
有明显的差异,比如
句法
问题域
图书馆
类型(一点)
但哪些是更微妙的?JavaScript编码器是否会认为在Lua中工作的东西略有不同?是否有任何陷阱对于有经验的编程人员尝试另一种语言而言可能并不明显?
例如:在Lua中,数组和散列不是分开的(只有表格) - 在JavaScript中,它们是数字数组和散列对象.嗯,这是一个比较明显的差异.
但是在变量范围,不变性或类似的东西方面是否存在差异?
更多的差异:
Lua本身就支持协同程序.
更新:JS现在在generator中包含yield关键字,为协程提供支持.
对于任何比较运算符,Lua 不会在类型之间进行转换.在JS中,只有===
并且!==
不要键入juggle.
Lua有一个取幂运算符(^
); JS没有.JS使用不同的运营商,包括三元条件操作符(?:
VS and/or
),并且,如5.3,位运算符(的&
,|
等与元方法).
更新:JS现在有了取幂运算符**
.
JS具有递增/递减,类型运算符(typeof
和instanceof
),附加赋值运算符和其他比较运算符.
在JS的==
,===
,!=
和!==
运营商都低于优先级>
,>=
,<
,<=
.在Lua中,所有比较运算符都具有相同的优先级.
Lua支持尾调用.
更新:JS现在支持尾调用.
Lua支持分配变量列表.虽然它在Javascript中尚未成为标准,但Mozilla的JS引擎(以及Opera在某种程度上)支持了自JS 1.7(作为Firefox 2的一部分提供)以" destructuring assignment " 命名的类似功能.JS中的解构更通用,因为它可以在除赋值之外的上下文中使用,例如函数定义和调用以及循环初始化器.解构分配已经成为ECMAScript(Javascript背后的语言标准)的一个建议的补充.
更新:解构(和解构分配)现在是ECMAScript规范的一部分 - 已在许多引擎中实现.
在Lua中,您可以重载运算符.
在Lua中,你可以操纵与环境getfenv
和setfenv
在Lua 5.1或_ENV
在Lua中5.2和5.3.
在JS中,所有函数都是可变的.在Lua中,函数必须显式声明为variadic.
Foreach
在JS中循环对象属性.的foreach在Lua中(其中使用关键字for
)遍历迭代器和更通用.
更新:JS 现在也有Iterables,其中许多内置于您期望的常规数据结构中,例如Array
.这些可以用for...of
语法循环.对于常规对象,可以实现自己的迭代器函数.这使它更接近Lua.
JS具有全局和功能范围.Lua具有全局和块范围.控制结构(例如if
,for
,while
)引入新的块.
由于范围规则的不同,闭包引用外部变量(在Lua用语中称为"upvalues")可能在Lua和Javascript中以不同方式处理.这种情况最常见于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)
因此,在单独的迭代中定义的函数对于每个引用的循环变量具有不同的upvalues.另见Nicolas Bola 在Lua中实现闭包的答案?和" 循环变量的闭包的正确语义是什么? "和" Generic for Seneric ".
更新:JS现在具有块范围.用块let
或const
范围定义的变量.
JS中的整数文字可以是八进制的.
JS具有明确的Unicode支持,内部字符串以UTF-16编码(因此它们是字节对的序列).各种内置JavaScript函数使用Unicode数据,例如"pâté".toUpperCase()
("PÂTÉ"
).Lua 5.3及更高版本在字符串文字中具有Unicode代码点转义序列(与JavaScript代码点转义序列具有相同的语法)以及内置utf8
库,它提供对UTF-8编码的基本支持(例如编码代码点)进入UTF-8并将UTF-8解码为代码点,获取字符串中的代码点数,并迭代代码点).Lua中的字符串是单个字节的序列,可以包含任何编码或任意二进制数据中的文本.Lua没有任何使用Unicode数据的内置函数; 行为string.upper
取决于C语言环境.
在Lua中的not
,or
,and
关键字代替使用JS的!
,||
,&&
.
Lua使用~=
"不相等",而JS使用!==
.例如,if foo ~= 20 then ... end
.
Lua 5.3及以上~
用于二进制按位异或,而JS使用 ^
.
在Lua中,任何类型的值(除了nil
和NaN
)都可以用来索引表; 在JavaScript中,所有非字符串类型(Symbol除外)在用于索引对象之前都会转换为字符串.
在JS中,赋值被视为表达式,但在Lua中它们不是.因此,JS允许条件下作业obj[1]
,"string one"
和"number one"
语句,但Lua中没有的obj = {}; obj[1] = "number one"; obj["1"] = "string one";
,if
和while
语句.例如,do while
是有效的JS,但是if
Lua是无效的.
LUA具有用于声明块范围的函数的变量,即是字段功能语法糖,和方法(while
,repeat until
,if (x = 'a') {}
).JS用等号(if x = 'a' do end
,local function() end
)声明这些.
一些微妙的差异,至少会抓住你一次:
~=
在Lua 拼写不相等.在JS中它是!=
Lua 数组是基于1的 - 它们的第一个索引是1而不是0.
Lua需要冒号而不是句点来调用对象方法.你写a:foo()
而不是a.foo()
†
†如果需要,可以使用句点,但必须self
明确传递变量.a.foo(a)
看起来有点累赘.有关详细信息,请参阅Lua编程.
说实话,列出Javascript和Lua常用的东西比列出差异更容易.它们都是动态类型的脚本语言,但这就是你可以实现的.它们具有完全不同的语法,不同的原始设计目标,不同的操作模式(Lua总是编译为字节码并在Lua VM上运行,Javascript不同),列表一直在继续.
JavaScript数组和对象比您想象的更接近.您可以使用数组表示法来获取其中任何一个的元素,并且可以向数组添加非数字索引.单个数组元素可以保存任何内容,并且数组可以是稀疏的.他们是几乎相同的堂兄弟.