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


121

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

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

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

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

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

Например: в Lua массивы и хеши не разделены (есть только таблицы) - в JavaScript это числовые массивы и хешированные объекты. Что ж, это одно из наиболее очевидных отличий.

Но есть ли различия в области видимости переменных, неизменяемости или чем-то подобном?


8
Для тех, кто, как я, искал общего сравнения и случайно оказался здесь, следующий хороший обзор: phrogz.net/lua/LearningLua_FromJS.html
Tao

Это серия из трех частей, в которых объясняются все различия, которые вам нужно знать, чтобы начать работу: oreilly.com/learning/…
charAt

Ответы:


189

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

  • Lua имеет встроенную поддержку сопрограмм .
    • ОБНОВЛЕНИЕ : JS теперь содержит ключевое слово yield внутри генераторов, что обеспечивает поддержку сопрограмм.
  • Lua не выполняет преобразование между типами ни для каких операторов сравнения. В JS только ===и !==не жонглируйте.
  • В Lua есть оператор возведения в степень ( ^); JS этого не делает. JS использует разные операторы, включая тернарный условный оператор ( ?:vs and/or) и, начиная с версии 5.3, побитовые операторы ( &, |и т. Д. По сравнению с метаметодами ).
    • ОБНОВЛЕНИЕ : JS теперь имеет оператор возведения в степень **.
  • JS имеет инкремент / декремент, операторы типов ( typeofи instanceof), дополнительные операторы присваивания и дополнительные операторы сравнения.
  • В JS , как ==, ===, !=и !==операторы имеют более низкий приоритет , чем >, >=, <, <=. В Lua все операторы сравнения имеют одинаковый приоритет .
  • Lua поддерживает хвостовые вызовы .
  • Lua поддерживает присвоение списку переменных . Хотя это еще не является стандартом для Javascript , движок Mozilla JS (и в некоторой степени Opera) поддерживает аналогичную функцию с JS 1.7 (доступную как часть Firefox 2) под названием « деструктурирующее назначение ». Деструктуризация в JS является более общей, поскольку ее можно использовать в контекстах, отличных от назначения, таких как определения и вызовы функций и инициализаторы цикла . Назначение деструктуризации было предложенным дополнением к ECMAScript (языковому стандарту Javascript) в течение некоторого времени.
    • ОБНОВЛЕНИЕ : Деструктуризация (и назначение деструктуризации) теперь является частью спецификации для ECMAScript - уже реализованной во многих движках.
  • В Lua вы можете перегружать операторы .
  • В Lua вы можете управлять средой с помощью getfenvиsetfenv в Lua 5.1 или _ENVв Lua 5.2 и 5.3 .
  • В JS все функции являются вариативными. В Lua функции должны быть явно объявлены как переменные .
  • Foreachв JS перебирает свойства объекта. Foreach в Lua (который использует ключевое слово for) перебирает итераторы и является более общим.
    • ОБНОВЛЕНИЕ : JS теперь также имеет Iterables , многие из которых встроены в обычные структуры данных, которые вы ожидаете, например Array. Их можно перебрать с помощью for...ofсинтаксиса. Для обычных объектов можно реализовать свои собственные функции итератора. Это приближает его к Lua.
  • JS имеет глобальную и функциональную область видимости. Lua имеет глобальную и блочную область видимости . Управляющие структуры (например if, for, while) ввести новые блоки .

    • Из-за различий в правилах области видимости ссылка на внешнюю переменную (называемая «upvalues» на языке Lua) может обрабатываться по-разному в 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)

      Как следствие, функции, определенные в отдельных итерациях, имеют разные значения для каждой переменной цикла, на которую указывает ссылка. См. Также ответы Николаса Бола на вопрос « Реализация закрытий в Lua?». и « Какова правильная семантика замыкания для переменной цикла? » и « Семантика универсального for ».

      ОБНОВЛЕНИЕ : JS теперь имеет блокировку. Переменные , определенные с letили constсоблюдение блока объема.

  • Целочисленные литералы в JS могут быть восьмеричными.
  • JS имеет явную поддержку Unicode, а внутренние строки кодируются в UTF-16 (поэтому они представляют собой последовательности пар байтов). Различные встроенные функции JavaScript используют данные Unicode, например "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 и выше имеют escape-последовательности кодовой точки Unicode в строковых литералах (с тем же синтаксисом, что и escape-последовательности кодовой точки 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 и выше используют ~двоичный побитовый XOR, тогда как JS использует ^.
  • В Lua любой тип значения (кроме nilи NaN) можно использовать для индексации таблицы. В JavaScript все нестроковые типы (кроме Symbol) преобразуются в строки перед использованием для индексации объекта. Например, после оценки следующего кода, значение obj[1]будет "string one"в JavaScript, но "number one"в Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • В JS присвоения обрабатываются как выражения, но в Lua это не так. Таким образом, 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 () {}).

6
в Lua логические операторы (и, или) действительно возвращают один из аргументов. все функции можно вызывать с любым количеством параметров; но настроены на необходимое число (если вы не используете ... 'дополнительные аргументы')
Хавьер

1
@RCIX: см. Luaconf.h (а в Lua 5.2 также lparser.c и llimits.h). Максимальное количество локальных значений / функция = 200 в Lua 5.1 и Lua 5.2. Максимальное значение upvalues ​​/ function = 60 в Lua 5.1, 255 в Lua 5.2 (и это количество включает также upvalues, "унаследованные" замыканиями, созданными внутри функции).
dubiousjim 01

8
Я думаю, вы можете добавить в список массивы, начинающиеся с единицы, это может сильно раздражать, когда вы к этому не привыкли.
Yann

2
Только nil и false являются ложными в Lua - так, например, 0 истинно в Lua, но не в js. О поддержке Unicode: Lua 5.3 добавляет некоторую явную поддержку UTF-8, а более старые версии Lua подходят для буферов UTF-8, хранящихся в строках (например, вы можете использовать Unicode в шаблонах поиска строк). Js-поддержка UTF-8 не идеальна, поскольку V8 внутренне использует старое 16-битное представление, поэтому ваши строки Unicode могут закончиться (что удивительно!) Суррогатными парами, которые не понадобятся в старом добром UTF-8 (и выиграли этого не происходит в Lua).
Тайлер

4
Мне понравился этот список, но я не понимаю, как ~=можно спровоцировать скрытые ошибки. Это может спровоцировать синтаксические ошибки , но они совсем не тонкие.
kikito

12

Пара тонких отличий, которые заметят хотя бы раз:

  • Не равно пишется ~=в Lua. В JS это!=
  • Массивы Lua начинаются с 1 - их первый индекс равен 1, а не 0.
  • Lua требует двоеточия, а не точки для вызова методов объекта. Вы пишете a:foo()вместо a.foo()

† при желании можно использовать точку, но selfпеременную необходимо передать явно. a.foo(a)выглядит немного громоздко. См. « Программирование на Lua» для подробностей.


5
использование для аннотации создает впечатление, что a.foo()он умер xD
DarkWiiPlayer

11

Если честно, было бы проще перечислить общие для Javascript и Lua вещи, чем перечислить различия. Они оба являются языками сценариев с динамической типизацией, но это все, что вы можете на самом деле. У них совершенно другой синтаксис, разные исходные цели дизайна, разные режимы работы (Lua всегда компилируется в байт-код и запускается на Lua VM, Javascript меняется), список можно продолжать и продолжать.


8
абсолютно. самые разные цели включают в себя высокий приоритет чистого языка. У Javascript много исторического багажа, Lua постоянно избавляется от всего нежелательного.
Хавьер

3
+1. Я даже не понимаю, насколько они вообще похожи, за исключением того факта, что они оба используются для написания сценариев (что слишком очевидно).
Саша Чедыгов

13
-1 (если бы мог) Они очень похожи в плане языкового дизайна. Lua просто имеет больше возможностей и меньше (тоже быстрее?). Я думаю, вы путаете языковой дизайн с вариантами реализации.
jpc

Да, они оба являются прототипами ООП (даже если это явно не указано с использованием ключевых слов prototypeили именования объектов объектов, несмотря на то, что это именно то, что представляют собой таблицы lua), с функциями как первоклассный гражданин, несмотря на то, что они не функционируют в традиционном смысле (неизменяемость , декларативная разработка и т. д.),
Боян Маркович

2
Конечно, есть синтаксические различия, и если вы посмотрите на это поверхностно, вы можете сделать вывод, что языки разные. Однако наличие одного и того же основного типа данных (объект / таблица) и одного и того же способа реализации классов и наследования (что есть у очень немногих других языков) делает их удивительно близкими по духу. Дизайн нетривиальной JS-программы будет примерно таким же, как у Lua.
Alex Gian

7

Массивы и объекты JavaScript ближе, чем вы думаете. Вы можете использовать нотацию массива, чтобы получить доступ к элементам любого из них, и вы можете добавлять нечисловые индексы к массивам. Отдельные элементы массива могут содержать что угодно, и массив может быть разреженным. Они почти идентичные кузены.


1
Можно ли иметь идентичных кузенов?
jameshfisher

Это одна и та же структура данных, единственное отличие - это дескриптор типа, поэтому вы можете отличить их друг от друга.
Lilith River

5
Более точное утверждение было бы следующим: Массивы - это объекты с особым поведением члена "длины".
tzenes

@eegg: конечно, Кэти и Пэтти .
outis

3

С верхней части моей головы

Lua ...

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

Луо делает имеют лексическую область. В JavaScript есть только функция. ну, в Mozilla и Rhino yo теперь может использовать let вместо var и получить правильную лексическую область видимости; но он еще не переносится.
Хавьер

1
Стандартная строковая библиотека Lua включает ограниченные функции сопоставления шаблонов; но есть также LPEG (также библиотека), который дает гораздо более мощную систему сопоставления, которую легко использовать для полной грамматики.
Хавьер

Я заявил, что у LUA «лучшая» лексическая область видимости, чем у javascript, но не то, чтобы у нее ее не было.
jitter

1
LPEG - это дополнительная библиотека, которая означает, что поддержка регулярных выражений ядра ограничена для меня
jitter

существует некоторое ограничение между строковыми ключами и числовыми ключами, использование обоих в одной таблице очень быстро становится беспорядочным, поскольку # возвращает длину таблицы, а не количество пронумерованных индексов, что будет конфликтовать с любой записью словаря (индексирование ноль после перечисления индексы таблиц)
Weeve Ferrelaine 01

3

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

Оба присваивают функции переменным, могут создавать функции на лету и определять замыкания.


1

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


1
Это очевидное сходство между двумя языками и использование ими таблиц / хэшей в качестве основного типа данных. Если бы вы разрабатывали программу на Javascript идиоматически, вы бы применили тот же подход, что и в Lua. Вы бы не сделали того же на любом другом языке (если только это не язык, основанный на наследовании прототипов и таблицах). Это огромное сходство. Остальное, подробности о второстепенном синтаксисе и так далее, по сравнению с ним довольно педантичны.
Alex Gian

1
Важные отличия заключаются в том, что Jaavscript не поддерживает сопрограммы, не очень тесно связан с C и не совсем подходит в качестве встроенного языка. (Сколько микроконтроллеры программируются в JavaScript?) Javascript также намного грязнее, с тоннами старых подводных камней и Уотс ( destroyallsoftware.com/talks/wat ) - от 1:40. В Lua наложена довольно спартанская дисциплина. Javascript, конечно, очень силен в браузере.
Alex Gian

1

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

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.