тонкие различия между JavaScript и Lua

Я просто люблю JavaScript. Это так элегантно (представьте себе тихий звук влюбленного поклонника, вздыхающего на заднем плане).

Итак, недавно я играл с Lua через löve2d рамки (Ницца!)- и я думаю, что Луа тоже великолепна. Они, как я вижу, эти два языка очень похожие.

есть очевидные различия, как

  • синтаксис
  • домен
  • библиотеки
  • типы (немного)

но какие из них более утонченные? Есть ли что-то, что кодер JavaScript будет принимать как должное, что работает в Lua немного иначе? Есть ли какие-то подводные камни, которые могут быть не очевидны для опытного кодера одного языка, пытающегося другой?

например: в Lua массивы и хэши не разделены (есть только таблицы) - в JavaScript они являются числовыми массивами и хэшируются Объекты. Это одно из наиболее очевидных различий.

но есть ли различия в переменной области, неизменяемости или что-то вроде этого?

8 ответов


еще несколько отличий:

  • Луа имеет встроенную поддержку для coroutines.
    • обновление: JS теперь содержит ключевое слово yield внутри генераторов, предоставляя ему поддержку coroutines.
  • Луа не преобразовывает между типов для любых операторов сравнения. В JS, только === и !== не типа жонглировать.
  • Луа есть оператор возведения в степень (^); JS нет. JS использует различные операторы, включая троичный условный оператор (?: vs and/or), и, начиная с 5.3, побитовые операторы (&, |, etc. против метаметоды ).
    • обновление: JS теперь имеет оператор возведения в степень **.
  • JS есть инкремент / декремент, операторы типа (typeof и instanceof), дополнительные операторы присваивания и дополнительные операторы сравнения.
  • на JS, the ==, ===, != и !== операторы имеют более низкий приоритет, чем >, >=, <, <=. В Lua, все операторы сравнения являются тот же приоритет.
  • Луа поддерживает хвост звонки.
  • Луа поддерживает присвоение списку переменных. Хотя это еще не стандарт в 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 имеет глобальный и функциональный объем. Луа и глобальная и блочная область. Структуры управления (например,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 ...

  1. поддерживает coroutines
  2. не имеет ограничений только на строку / номер в качестве ключа для таблицы. Все работает.
  3. обработка ошибок несколько неуклюжа. Либо вы ничего не обрабатываете, либо используете pcall метод
  4. Я думаю, что я читал что-то о различиях в лексической области и что Lua имеет лучший.
  5. если я правильно помню поддержка регулярных выражений в lua ограничена

Мне понравился этот вопрос и ответы. Дополнительные причины два языка кажутся мне более похожими, чем не мне:

Как назначение функций переменным, может создавать функции на лету, и определить закрытие.


тест показывает, что текущий Javascript также возвращает объекты или, по крайней мере, строки из логических выражений, таких как lua:

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

Lua и JavaScript являются базовыми языками прототипов.