тонкі відмінності між JavaScript та Lua [закрито]


121

Я просто люблю JavaScript. Це так елегантно (уявіть тихий звук коханого фанбука, який зітхає на задньому плані).

Отже, нещодавно я грав з Lua через рамки löve2d (приємно!) - і я думаю, що Lua також чудовий. Як я бачу, ці дві мови дуже схожі.

Існують очевидні відмінності, як

  • синтаксис
  • проблемний домен
  • бібліотеки
  • типи (трохи)

але які більш тонкі? Чи є щось, що JavaScript-кодер сприймається як належне, що працює в Луа просто дещо інакше? Чи є якісь підводні камені, які можуть не бути очевидними для досвідченого кодера однієї мови, який пробує інший?

Наприклад: у Lua масиви та хеші не є окремими (є лише таблиці) - у JavaScript це числові масиви та хешовані об'єкти. Ну, це одна з найбільш очевидних відмінностей.

Але чи існують відмінності в змінному обсязі, незмінність чи щось подібне?


8
Для тих, як я, хто шукав загальне порівняння і опинився тут випадково, наступний приємний огляд: phrogz.net/lua/LearningLua_FromJS.html
Тао

Це три серії частини , яка пояснює все відмінності ви повинні знати , щоб почати роботу: oreilly.com/learning / ...
Куля

Відповіді:


189

Ще кілька відмінностей:

  • У Луа є підтримка корутин .
    • ОНОВЛЕННЯ : JS тепер містить ключове слово прибутковість всередині генераторів, надаючи йому підтримку для супроводу.
  • Lua не конвертує між типами для жодних операторів порівняння. У JS лише ===та !==не вводите жонглювання.
  • У Луа є оператор експоненції ( ^); JS ні. JS використовує різні оператори, включаючи потрійний умовний оператор ( ?:vs and/or), і, на 5.3, побітові оператори ( &, |і т.д. проти метаметодів ).
    • ОНОВЛЕННЯ : JS тепер має оператора експоненції **.
  • JS має збільшення / зменшення, оператори типу ( typeofі instanceof), додаткові оператори присвоєння та додаткові оператори порівняння.
  • В JS , як ==, ===, !=і !==оператори мають більш низький пріоритет , ніж >, >=, <, <=. У Луї всі оператори порівняння мають однаковий пріоритет .
  • Lua підтримує хвостові дзвінки .
  • Lua підтримує призначення списку змінних . Незважаючи на те, що він ще не є стандартним у Javascript , JS-двигун Mozilla (і Опера, в значній мірі) підтримує подібну функцію, оскільки JS 1.7 (доступна як частина Firefox 2) під назвою " деструктуризація ". Деструктурування в JS є більш загальним, оскільки його можна використовувати в інших контекстах, крім призначення, таких як визначення функцій та виклики та ініціалізатори циклу . Призначення деструктуризації було запропонованим доповненням до ECMAScript (мовного стандарту Javascript) на деякий час.
    • ОНОВЛЕННЯ : Деструктуризація (і призначення деструктуризації) тепер є частиною специфікації для ECMAScript - вже впровадженої у багатьох двигунах.
  • У Луа можна перевантажувати операторів .
  • У Lua , ви можете маніпулювати середовища з getfenvіsetfenv в Lua 5.1 або _ENVв Lua 5.2 і 5.3 .
  • У JS всі функції різноманітні. У Lua функції повинні бути чітко оголошені як різноманітні .
  • Foreachв JS- петлях над властивостями об'єкта. Програмуйте в Луа (які використовують ключове слово for), петлі над ітераторами і є більш загальним.
    • ОНОВЛЕННЯ : JS також має Iterables , багато з яких вбудовані у звичайні структури даних, які ви очікували, такі як Array. Вони можуть бути перекинуті на for...ofсинтаксис. Для звичайних Об'єктів можна реалізувати власні функції ітератора. Це зближує його з Луєю.
  • 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)
      

      Як наслідок, функції, визначені в окремих ітераціях, мають різні значення для кожної змінної циклу, на яку посилається. Дивіться також відповіді Ніколя Бола на " Впровадження закриттів у Луа"? і " Які правильні семантики замикання на змінну циклу? ", і " Семантика загального для ".

      ОНОВЛЕННЯ : 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 і вище використовувати ~для бінарних побітових XOR, тоді як JS використовує ^.
  • У Луа будь-який тип значення (крім nilі NaN) може використовуватися для індексації таблиці. У JavaScript всі нерядкові типи (крім Symbol) перетворюються на рядки перед тим, як використовуватись для індексації об'єкта. Наприклад, після оцінки наступного коду, значення obj[1]буде "string one"в JavaScript, але "number one"в Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • У 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 () {}).

6
в Lua логічні оператори (і, або) повертають один з аргументів. всі функції можна викликати з будь-якою кількістю параметрів; але налаштовуються на потрібну кількість (якщо ви не використовуєте ... "додаткові арги")
Хав'єр

1
@RCIX: див. Luaconf.h (а в Lua 5.2 також lparser.c та llimits.h). Максимальні локальні значення / функції = 200 у Lua 5.1 та Lua 5.2. Максимальне значення / функція = 60 в Lua 5.1, 255 в Lua 5.2 (і цей рахунок включає також додаткові значення, «успадковані» закриттями, створеними всередині функції).
сумнівним

8
Я думаю, ви можете додати до списку масиви на основі 1, це може бути дуже прикро, коли ви до цього не звикли.
Янв

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

4
Мені сподобався цей список, але я не бачу, як ~=можуть спровокувати тонкі помилки. Це може спровокувати синтаксичні помилки , але вони зовсім не тонкі.
кікіто

12

Кілька тонких відмінностей, які вас привернуть хоча б один раз:

  • Не рівне написано ~=в Луа. У JS це так!=
  • Масиви Lua базуються на 1 - їх перший індекс 1, а не 0.
  • Для виклику об'єктних методів Lua потрібен двокрапка, а не період. Ви пишете a:foo()замість a.foo()

ви можете використовувати період, якщо хочете, але повинні передати selfзмінну явно. a.foo(a)виглядає трохи громіздко. Детальніше див. У програмі Луа .


5
використовуючи для анотування створює враження , що a.foo()помер XD
DarkWiiPlayer

11

Якщо чесно, то було б простіше перелічити речі, які є спільними для Javascript та Lua, ніж перелічити відмінності. Вони обидві динамічно набрані мови сценаріїв, але це приблизно так, наскільки ви дійсно можете піти. Вони мають абсолютно різний синтаксис, різні оригінальні цілі дизайну, різні режими роботи (Lua завжди компілюється для байт-коду та працює у Lua VM, Javascript змінюється), список продовжується та продовжується.


8
абсолютно. дуже різні цілі включають високий пріоритет щодо чистої мови. У Javascript багато історичного багажу, Lua постійно проливає все, що небажано.
Хав'єр

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

13
-1 (якщо я міг) Вони дуже схожі на мовній частині дизайну. У Луа просто більше функцій і менше (також швидше?). Думаю, ви плутаєте дизайн мови з вибором реалізації.
jpc

Так, вони є обома прототипами OOP (навіть якщо це прямо не вказано за допомогою ключових слів prototypeабо іменування об'єктів об'єктів, незважаючи на те, що саме такі таблиці є lua), з функціями як громадяни першого класу, незважаючи на те, що вони не функціонують у традиційному розумінні (імутаблілітність , декларативний розвиток тощо),
Боян Маркович

2
Звичайно, є синтаксичні відмінності, і якщо ви дивитесь на це поверхово, ви можете зробити висновок, що мови різні. Однак наявність абсолютно однакового основного типу даних (об'єкт / таблиця) та однаковий спосіб реалізації класів та успадкування (те, на що поділяють дуже мало інших мов) робить їх надзвичайно близькими за духом. Дизайн нетривіальної програми JS був би майже таким же, як і у Lua.
Алекс Джан

7

Масиви та об’єкти JavaScript ближчі, ніж ви могли подумати. Ви можете використовувати позначення масиву, щоб отримати елементи будь-якого з них, а ви можете додати нечислові індекси до масивів. Окремі елементи масиву можуть містити все, що завгодно, а масив може бути рідким. Вони майже однакові родички.


1
Чи можна мати однакових двоюрідних братів?
jameshfisher

Вони однакові структури даних, єдина різниця - це дескриптор типу, щоб ви могли їх розрізнити.
Річка Ліліт

5
Більш точним твердженням було б: масиви - це об'єкти з особливою поведінкою їх "довжини" члена.
tzenes

@eegg: звичайно, Кеті та Патті .
outis

3

З верхньої частини голови

Луа ...

  1. підтримує супроводи
  2. не має обмеження лише рядок / число як ключ для таблиці. Все працює.
  3. обробка помилок дещо незграбна. Або ви нічого не впораєтеся або не використовуєте метод pcall
  4. Я думаю, що я прочитав щось про відмінності в лексичному просторі і про те, що Луа є кращим.
  5. Якщо я правильно пригадую, підтримка регулярного вираження в луї обмежена

Луо робить мають лексичну область. JavaScript має лише функціональну область. добре, що в Mozilla та Rhino yo зараз можуть використовувати «нехай» замість «var» та отримувати належні лексичні рамки; але це ще не портативно.
Хав'єр

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

Я заявив, що LUA має "кращу" лексичну сферу, ніж javascript, що не має.
тремтіння

1
LPEG - це додаткова бібліотека, яка означає, що підтримка ядра для регулярних виразів обмежена мною
тремтіння

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

3

Мені сподобалось це запитання та надані відповіді. Додаткові причини обидві мови здаються мені більш схожими, ніж не:

Обидва присвоюють функції змінним, можуть будувати функції на ходу та визначати закриття.


1

Lua та JavaScript - обидві базові мови прототипу.


1
Це очевидна схожість між двома мовами, цією та їх використанням таблиць / хешів як основного типу даних. Якби ви розробляли програму Javascript ідіоматично, ви б скористалися майже таким же підходом, як і у Луї. Ви б не зробили те ж саме в іншій мові (якщо тільки мова не базується на успадкуванні прототипу та таблицях). Це величезна схожість. Решта, деталі про другорядний синтаксис тощо - порівняно педантичні.
Алекс Джан

1
Важливі відмінності полягають у тому, що Jaavscript не підтримує взаємопрограми, не дуже щільно поєднаний з C і не дуже підходить як вбудована мова. (Скільки мікроконтролери програмуються в JavaScript?) Javascript також набагато брудніше, з тоннами старих підводних каменів і Уотс ( destroyallsoftware.com/talks/wat ) - від 1:40. У Луа була нав'язана досить спартанська дисципліна. Javascript, звичайно, дуже сильний у браузері.
Алекс Джан

1

Тест показує, що поточний Javascript також повертає об'єкти або, принаймні, рядки з логічних виразів, як lua:

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