тонкие различия между 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 каждая итерацияforloop создает новые локальные переменные для каждого цикла переменная.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();