тонкие различия между JavaScript и Lua
Я просто люблю JavaScript. Это так элегантно (представьте себе тихий звук влюбленного поклонника, вздыхающего на заднем плане).
Итак, недавно я играл с Lua через löve2d рамки (Ницца!)- и я думаю, что Луа тоже великолепна. Они, как я вижу, эти два языка очень похожие.
есть очевидные различия, как
- синтаксис домен
- библиотеки
- типы (немного)
но какие из них более утонченные? Есть ли что-то, что кодер JavaScript будет принимать как должное, что работает в Lua немного иначе? Есть ли какие-то подводные камни, которые могут быть не очевидны для опытного кодера одного языка, пытающегося другой?
например: в Lua массивы и хэши не разделены (есть только таблицы) - в JavaScript они являются числовыми массивами и хэшируются Объекты. Это одно из наиболее очевидных различий.
но есть ли различия в переменной области, неизменяемости или что-то вроде этого?
8 ответов
еще несколько отличий:
-
Луа имеет встроенную поддержку для coroutines.
- обновление: JS теперь содержит ключевое слово yield внутри генераторов, предоставляя ему поддержку coroutines.
-
Луа не преобразовывает между типов для любых операторов сравнения. В JS, только
===
и!==
не типа жонглировать. -
Луа есть оператор возведения в степень (
^
); JS нет. JS использует различные операторы, включая троичный условный оператор (?:
vsand/or
), и, начиная с 5.3, побитовые операторы (&
,|
, etc. против метаметоды ).-
обновление: JS теперь имеет оператор возведения в степень
**
.
-
обновление: JS теперь имеет оператор возведения в степень
-
JS есть инкремент / декремент, операторы типа (
typeof
иinstanceof
), дополнительные операторы присваивания и дополнительные операторы сравнения. - на JS, the
==
,===
,!=
и!==
операторы имеют более низкий приоритет, чем>
,>=
,<
,<=
. В Lua, все операторы сравнения являются тот же приоритет. -
Луа поддерживает хвост звонки.
- обновление: JS сейчас поддержка хвостовых вызовов.
-
Луа поддерживает присвоение списку переменных. Хотя это еще не стандарт в Javascript, движок Mozilla JS (и Opera, в некоторой степени) поддерживает аналогичную функцию с JS 1.7 (доступный как часть Firefox 2) под названием "реструктуризующее присваивание". Деконструкция в JS более общий, поскольку он может использоваться в контекстах, отличных от назначения, таких как определения функций и вызовы и петли инициализаторы. Реструктуризующее присваивание было предложено дополнение к ECMAScript (стандарт языка за Javascript) на некоторое время.
- обновление: деструктурирование (и назначение деструктурирования) теперь является частью спецификации для ECMAScript - уже реализовано во многих двигатели.
- на Луа вы можете перегрузка операторов.
- на Луа, вы можете манипулировать средах с
getfenv
иsetfenv
в Lua 5.1 или_ENV
на Lua 5.2 и 5.3. - на JS все функции с переменным числом аргументов. В Луа функции должны быть явно объявлены как variadic.
-
Foreach
на JS перебирает свойства объекта. Foreach на Луа (которые используют ключевое словоfor
) циклы над итераторами и более общие.-
обновление: JS имеет Iterables теперь тоже, многие из которых встроены в обычные структуры данных, которые вы ожидаете, такие как
Array
. Они могут быть зациклены наfor...of
синтаксис. Для обычных объектов можно реализуют собственные функции итератора. Это приближает его к Lua.
-
обновление: JS имеет Iterables теперь тоже, многие из которых встроены в обычные структуры данных, которые вы ожидаете, такие как
-
JS имеет глобальный и функциональный объем. Луа и глобальная и блочная область. Структуры управления (например,
if
,for
,while
) ввести новый блоки.-
из-за различий в правилах области видимости ссылка закрытия внешней переменной (называемой "upvalues" на языке Lua) может обрабатываться по-разному в Lua и в Javascript. Это чаще всего происходит с закрытие в
for
петли, и застает некоторых людей врасплох. В Javascript телоfor
цикл не вводит новую область, поэтому любые функции, объявленные в теле цикла, ссылаются на те же внешние переменные. В Lua каждая итерацияfor
loop создает новые локальные переменные для каждого цикла переменная.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 для каждой ссылочной переменной цикла. См. также ответы Николаса болы на реализация закрытия в Lua? и "какова правильная семантика закрытия над переменной цикла?" и "семантика родового для".
обновление: JS теперь имеет область блока. Переменные с
let
илиconst
уважаю область блока.
-
- целочисленные литералы в JS может быть в восьмеричной.
- JS имеет явную поддержку Unicode.
- на Луа, the
not
,or
,and
ключевые слова используются вместо JS ' s!
,||
,&&
. -
Луа использует
~=
для "не равно", а JS использует!==
. Например,if foo ~= 20 then ... end
. -
Lua 5.3 и
~
для двоичного побитового XOR, тогда как JS использует^
. - на Луа любой тип значения (за исключением
nil
иNaN
) может использоваться для индексации таблицы; в JavaScript, все нестроковые типы (кроме символа) преобразуются в строки перед использованием для индексации объекта. - на JS, назначения рассматриваются как выражения, но в Луа это не так. Таким образом, JS допускает назначения в условиях
if
,while
иdo while
заявления, но Lua не вif
,while
иrepeat until
заявления. Например,if (x = 'a') {}
действительно JS, ноif x = 'a' do end
недействителен Lua. -
Луа имеет синтаксический сахар для объявления блочной функции переменные, функции, являющиеся полями, и методы (
local function() end
,function t.fieldname() end
,function t:methodname() end
). JS объявляет их со знаком равенства (let funcname = function optionalFuncname() {}
,objectname.fieldname = function () {}
).
честно говоря, было бы проще перечислить вещи, которые являются общими для Javascript и Lua, чем перечислять различия. Они оба являются динамически типизированными языками сценариев, но это примерно то, что вы можете сделать на самом деле. У них совершенно другой синтаксис, разные цели оригинального дизайна, разные режимы работы (Lua всегда компилируется в байт-код и запускается на Lua VM, Javascript меняется), список продолжается и продолжается.
пара тонких различий, которые поймают вас, по крайней мере, один раз:
- не равно пишется
~=
in Lua. В JS это!=
- Луа массивы с 1 - первый индекс 1, а не 0.
- Lua требует двоеточия, а не периода для вызова методов объекта. Ты пишешь
a:foo()
вместоa.foo()
†
† вы можете использовать период, если вы хотите, но чтобы пройти self
переменной в явном виде. a.foo(a)
выглядит немного громоздким. См.программирование в Lua для сведения.
массивы и объекты JavaScript ближе, чем вы думаете. Вы можете использовать нотацию массива, чтобы получить элементы любого из них, и вы можете добавить нечисловые индексы в массивы. Отдельные элементы массива могут содержать что угодно, а массив может быть разреженным. Они почти братья-близнецы.
с макушки моей головы
Lua ...
- поддерживает coroutines
- не имеет ограничений только на строку / номер в качестве ключа для таблицы. Все работает.
- обработка ошибок несколько неуклюжа. Либо вы ничего не обрабатываете, либо используете pcall метод
- Я думаю, что я читал что-то о различиях в лексической области и что Lua имеет лучший.
- если я правильно помню поддержка регулярных выражений в lua ограничена
Мне понравился этот вопрос и ответы. Дополнительные причины два языка кажутся мне более похожими, чем не мне:
Как назначение функций переменным, может создавать функции на лету, и определить закрытие.
тест показывает, что текущий Javascript также возвращает объекты или, по крайней мере, строки из логических выражений, таких как lua:
function nix(){
alert(arguments[0]||"0");
}
nix();