ความแตกต่างเล็กน้อยระหว่าง JavaScript และ Lua [ปิด]


121

ฉันชอบ JavaScript มันดูหรูหรามาก (ลองนึกภาพเสียงอันเงียบสงบของแฟนบอย lovestruck ที่กำลังถอนหายใจอยู่เบื้องหลัง)

เมื่อเร็ว ๆ นี้ฉันได้เล่นกับ Lua ผ่านlöve2d framework (ดีมาก!) - และฉันคิดว่า Lua ก็ยอดเยี่ยมเช่นกัน อย่างที่ฉันเห็นสองภาษานั้นคล้ายกันมาก

มีความแตกต่างที่ชัดเจนเช่น

  • วากยสัมพันธ์
  • โดเมนปัญหา
  • ห้องสมุด
  • ประเภท (บิต)

แต่อันไหนละเอียดกว่ากัน? มีอะไรที่ตัวเข้ารหัส JavaScript จะยอมรับว่าทำงานใน Lua แตกต่างกันเล็กน้อยหรือไม่? มีข้อผิดพลาดใด ๆ ที่อาจไม่ชัดเจนสำหรับผู้มีประสบการณ์ของภาษาหนึ่งที่พยายามใช้อีกภาษาหนึ่งหรือไม่?

ตัวอย่างเช่นใน Lua อาร์เรย์และแฮชจะไม่แยกจากกัน (มีเฉพาะตาราง) - ใน JavaScript เป็นอาร์เรย์ที่เป็นตัวเลขและวัตถุที่แฮช นี่คือหนึ่งในความแตกต่างที่ชัดเจนมากขึ้น

แต่มีความแตกต่างในขอบเขตตัวแปรไม่เปลี่ยนรูปหรืออะไรทำนองนี้?


8
สำหรับผู้ที่กำลังมองหาการเปรียบเทียบโดยรวมและจบลงที่นี่โดยบังเอิญสิ่งต่อไปนี้เป็นภาพรวมที่ดี: phrogz.net/lua/LearningLua_FromJS.html
Tao

นี่คือซีรีส์สามส่วนที่อธิบายความแตกต่างทั้งหมดที่คุณต้องรู้เพื่อเริ่มต้น: oreilly.com/learning/…
charAt

คำตอบ:


189

ความแตกต่างเพิ่มเติม:

  • Luaมีการสนับสนุนพื้นเมืองสำหรับcoroutines
    • อัปเดต : ขณะนี้ JS มีคีย์เวิร์ดผลตอบแทนในเครื่องกำเนิดไฟฟ้าซึ่งให้การสนับสนุนโครูทีน
  • Lua ไม่แปลงระหว่างประเภทสำหรับตัวดำเนินการเปรียบเทียบใด ๆ ใน JS เท่านั้น===และ!==อย่าพิมพ์เล่นกล
  • Luaมีตัวดำเนินการยกกำลัง ( ^); JSไม่ JSใช้ประกอบการที่แตกต่างกันรวมทั้งผู้ประกอบการที่มีเงื่อนไข ternary ( ?:VS and/or) และเป็น 5.3 ผู้ประกอบการระดับบิต ( &, |ฯลฯ กับmetamethods )
    • อัปเดต : JS มีตัวดำเนินการเลขชี้กำลัง**แล้ว
  • JSมีการเพิ่ม / ลดตัวดำเนินการประเภท ( typeofและinstanceof) ตัวดำเนินการกำหนดเพิ่มเติมและตัวดำเนินการเปรียบเทียบเพิ่มเติม
  • ในJSที่==, ===, !=และ!==ผู้ประกอบการที่มีความสำคัญต่ำกว่า>, >=, ,< <=ใน Lua ทั้งหมดดำเนินการเปรียบเทียบมีความสำคัญเช่นเดียวกัน
  • Luaสนับสนุนโทรหาง
  • Luaสนับสนุนที่ได้รับมอบหมายไปยังรายการของตัวแปร แม้ว่าจะยังไม่เป็นมาตรฐานในJavascriptแต่ JS engine ของ Mozilla (และ Opera's ในระดับหนึ่ง) ได้สนับสนุนคุณลักษณะที่คล้ายกันตั้งแต่ JS 1.7 (พร้อมใช้งานเป็นส่วนหนึ่งของ Firefox 2) ภายใต้ชื่อ " การกำหนดโครงสร้างการทำลาย " Destructuring ใน JS เป็นทั่วไปมากขึ้นเท่าที่จะสามารถนำมาใช้ในบริบทอื่น ๆ นอกเหนือจากที่ได้รับมอบหมายเช่นคำจำกัดความของฟังก์ชั่นและการโทรและinitializers ห่วง การกำหนดโครงสร้างการทำลายเป็นข้อเสนอเพิ่มเติมสำหรับ ECMAScript (มาตรฐานภาษาที่อยู่เบื้องหลัง Javascript) เป็นระยะเวลาหนึ่ง
    • อัปเดต : ตอนนี้การทำลายโครงสร้าง (และการกำหนดโครงสร้างการทำลาย) เป็นส่วนหนึ่งของข้อมูลจำเพาะสำหรับ ECMAScript ซึ่งมีการใช้งานแล้วในหลายเครื่องยนต์
  • ในLuaคุณสามารถโอเวอร์โหลดตัวดำเนินการได้
  • ในLuaคุณสามารถจัดการกับสภาพแวดล้อมที่มีgetfenvและsetfenvใน Lua 5.1 หรือ_ENVในLua 5.2และ5.3
  • ในJSฟังก์ชันทั้งหมดจะแปรผัน ในLua , ฟังก์ชั่นจะต้องมีการประกาศอย่างชัดเจนว่า variadic
  • 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)

      ด้วยเหตุนี้ฟังก์ชันที่กำหนดในการทำซ้ำแยกกันจึงมีการเพิ่มค่าที่แตกต่างกันสำหรับตัวแปรลูปที่อ้างอิงแต่ละตัว ดูคำตอบของ Nicolas Bola สำหรับการดำเนินการปิดใน Lua หรือไม่? และ " ความหมายที่ถูกต้องของการปิดทับตัวแปรลูปคืออะไร " และ " ความหมายของสามัญสำหรับ "

      UPDATE : 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! 's ||, &&,
  • Luaใช้~=สำหรับ "ไม่เท่ากัน" ขณะที่JS!==ใช้ ตัวอย่างเช่นif foo ~= 20 then ... end.
  • Lua 5.3และการใช้งานขึ้น~สำหรับ XOR บิตไบนารีขณะJS^ใช้
  • ในLuaสามารถใช้ค่าประเภทใดก็ได้ (ยกเว้นnilและNaN) เพื่อสร้างดัชนีตาราง ในJavaScriptประเภทที่ไม่ใช่สตริงทั้งหมด (ยกเว้น Symbol) จะถูกแปลงเป็นสตริงก่อนที่จะใช้ในการทำดัชนีวัตถุ ตัวอย่างเช่นหลังจากการประเมินผลของรหัสต่อไปนี้ค่าของการobj[1]จะเป็น"string one"ใน JavaScript แต่"number one"ใน obj = {}; obj[1] = "number one"; obj["1"] = "string one";Lua:
  • ในJS การมอบหมายงานจะถือว่าเป็นนิพจน์ แต่ในLuaนั้นไม่ใช่ ดังนั้น JS ช่วยให้ได้รับมอบหมายในเงื่อนไขของif, whileและdo whileงบ แต่ Lua ไม่ได้ในif, whileและrepeat untilงบ ตัวอย่างเช่นif (x = 'a') {}เป็น JS ที่ถูกต้อง แต่if x = 'a' do endLua ไม่ถูกต้อง
  • Luaมีน้ำตาลประโยคสำหรับประกาศบล็อกขอบเขตตัวแปรฟังก์ชั่นการทำงานที่มีเขตข้อมูลและวิธีการ ( local function() end, function t.fieldname() end, function t:methodname() end) JSประกาศสิ่งเหล่านี้ด้วยเครื่องหมายเท่ากับ ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {})

6
ใน Lua ตัวดำเนินการเชิงตรรกะ (และหรือ) จะส่งคืนหนึ่งในอาร์กิวเมนต์ ฟังก์ชันทั้งหมดสามารถเรียกใช้ด้วยพารามิเตอร์จำนวนเท่าใดก็ได้ แต่จะปรับเป็นจำนวนที่ต้องการ (เว้นแต่คุณจะใช้ ... 'extra args')
Javier

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 (และจำนวนนี้รวมค่า upvalues ​​"สืบทอดโดย" ที่สร้างขึ้นภายในฟังก์ชันด้วย)
พิรุธ

8
ฉันคิดว่าคุณสามารถเพิ่มอาร์เรย์แบบ 1 ฐานลงในรายการได้มันอาจจะค่อนข้างน่ารำคาญเมื่อคุณไม่คุ้นเคย
ยาน

2
เฉพาะศูนย์และเท็จเท่านั้นที่เป็นเท็จใน Lua - ตัวอย่างเช่น 0 คือความจริงใน Lua แต่ไม่ใช่ใน js เกี่ยวกับการรองรับ Unicode: Lua 5.3 เพิ่มการรองรับ UTF-8 ที่ชัดเจนและ Lua เวอร์ชันเก่าจะเป็นมิตรกับบัฟเฟอร์ UTF-8 ที่อยู่ในสตริง (เช่นคุณสามารถใช้ Unicode ในรูปแบบการค้นหาสตริง) การสนับสนุน Js ของ UTF-8 นั้นไม่สมบูรณ์แบบเนื่องจาก V8 ภายในใช้การแสดง 16 บิตแบบเก่าดังนั้นสตริง Unicode ของคุณอาจลงเอยด้วยคู่ตัวแทน (แปลกใจ!) ที่ไม่จำเป็นสำหรับ UTF-8 ที่ดี (และได้รับรางวัล ไม่เกิดขึ้นในลัวะ)
Tyler

4
ฉันชอบรายการนี้ แต่ฉันไม่เห็นว่า~=สามารถกระตุ้นข้อบกพร่องที่ลึกซึ้งได้อย่างไร อาจกระตุ้นให้เกิดข้อผิดพลาดทางไวยากรณ์ได้แต่ก็ไม่ละเอียดอ่อนเลย
kikito

12

ความแตกต่างเล็กน้อยที่จะดึงดูดคุณอย่างน้อยหนึ่งครั้ง:

  • สะกดไม่เท่ากัน~=ใน Lua ใน JS นั้นคือ!=
  • อาร์เรย์ Lua เป็นแบบ 1 - ดัชนีแรกคือ 1 แทนที่จะเป็น 0
  • Lua ต้องการเครื่องหมายจุดคู่แทนที่จะเป็นช่วงเวลาในการเรียก object method คุณเขียนa:foo()แทนa.foo()

คุณสามารถใช้จุดได้หากต้องการ แต่ต้องส่งผ่านselfตัวแปรอย่างชัดเจน a.foo(a)ดูยุ่งยากเล็กน้อย ดูการเขียนโปรแกรมใน Luaสำหรับรายละเอียด


5
การใช้คำอธิบายประกอบทำให้ดูเหมือนว่าa.foo()xD เสียชีวิตไปแล้ว
DarkWiiPlayer

11

พูดตามตรงมันจะง่ายกว่าที่จะแสดงรายการสิ่งที่เป็นเรื่องธรรมดาของ Javascript และ Lua มากกว่าการแสดงความแตกต่าง ทั้งสองเป็นภาษาสคริปต์ที่พิมพ์แบบไดนามิก แต่นั่นก็เท่าที่คุณจะทำได้ พวกเขามีไวยากรณ์ที่แตกต่างกันโดยสิ้นเชิงเป้าหมายการออกแบบดั้งเดิมที่แตกต่างกันโหมดการทำงานที่แตกต่างกัน (Lua ถูกรวบรวมเป็น bytecode เสมอและทำงานบน Lua VM, Javascript แตกต่างกันไป) รายการจะดำเนินต่อไป


8
อย่างแน่นอน เป้าหมายที่แตกต่างกันมาก ได้แก่ ลำดับความสำคัญสูงในการมีภาษาที่ชัดเจน Javascript มีสัมภาระในอดีตจำนวนมาก Lua ยังคงกำจัดทุกสิ่งที่ไม่ต้องการอย่างต่อเนื่อง
Javier

3
+1 ฉันไม่เห็นว่ามันคล้ายกันเลยยกเว้นว่าทั้งคู่ใช้สำหรับการเขียนสคริปต์ (ซึ่งชัดเจนเกินไป)
Sasha Chedygov

13
-1 (ถ้าทำได้) พวกมันคล้ายกันมากที่ด้านหน้าการออกแบบภาษา Lua มีคุณสมบัติมากกว่าและมีขนาดเล็กกว่า (เร็วกว่าด้วย?) ฉันคิดว่าคุณสับสนระหว่างการออกแบบภาษากับตัวเลือกการใช้งาน
jpc

ใช่พวกเขาทั้งสองเป็น OOP ต้นแบบ (แม้ว่าจะไม่ได้ระบุไว้อย่างชัดเจนโดยใช้คีย์เวิร์ดprototypeหรือการตั้งชื่ออ็อบเจกต์แม้ว่าข้อเท็จจริงที่ว่าคือตาราง lua ก็ตาม) โดยมีหน้าที่เป็นพลเมืองชั้นหนึ่งแม้ว่าจะไม่ได้ใช้งานตามความหมายดั้งเดิมก็ตาม (ความไม่เปลี่ยนแปลง , การพัฒนาที่เปิดเผยเป็นต้น),
Bojan Markovic

2
แน่นอนว่ามีความแตกต่างทางวากยสัมพันธ์และหากคุณดูเผินๆคุณอาจสรุปได้ว่าภาษาต่างกัน อย่างไรก็ตามการมีประเภทข้อมูลหลัก (object / table) ที่เหมือนกันทุกประการและการใช้คลาสและการสืบทอด (สิ่งที่มีภาษาอื่น ๆ ไม่กี่ภาษาแบ่งปัน) ทำให้พวกเขามีความใกล้ชิดกันอย่างน่าอัศจรรย์ การออกแบบโปรแกรม JS ที่ไม่สำคัญจะค่อนข้างเหมือนกับของ Lua
Alex Gian

7

อาร์เรย์และวัตถุ JavaScript อยู่ใกล้กว่าที่คุณคิด คุณสามารถใช้สัญกรณ์อาร์เรย์เพื่อรับองค์ประกอบขององค์ประกอบใดองค์ประกอบหนึ่งและคุณสามารถเพิ่มดัชนีที่ไม่ใช่ตัวเลขให้กับอาร์เรย์ได้ องค์ประกอบอาร์เรย์แต่ละรายการสามารถเก็บอะไรก็ได้และอาร์เรย์สามารถเบาบาง พวกเขาเกือบจะเหมือนลูกพี่ลูกน้องกัน


1
สามารถมีลูกพี่ลูกน้องที่เหมือนกันได้หรือไม่?
jameshfisher

โครงสร้างเหล่านี้เป็นโครงสร้างข้อมูลเดียวกันข้อแตกต่างเพียงอย่างเดียวคือตัวบอกประเภทเพื่อให้คุณสามารถแยกความแตกต่างได้
Lilith River

5
คำสั่งที่แม่นยำกว่าคืออาร์เรย์คือออบเจ็กต์ที่มีพฤติกรรมพิเศษของสมาชิก "ความยาว"
tzenes

@eegg: แน่ใจว่าเคธี่และแพตตี้
outis

3

ปิดด้านบนของหัวของฉัน

ลัวะ ...

  1. รองรับcoroutines
  2. ไม่มีข้อ จำกัด เพียงแค่สตริง / ตัวเลขเป็นกุญแจสำหรับตาราง ทุกอย่างใช้งานได้
  3. การจัดการข้อผิดพลาดค่อนข้างเงอะงะ ไม่ว่าคุณจะไม่จัดการอะไรเลยหรือใช้วิธีpcall
  4. ฉันคิดว่าฉันอ่านบางอย่างเกี่ยวกับความแตกต่างในขอบเขตคำศัพท์และ Lua มีสิ่งที่ดีกว่า
  5. หากฉันจำได้ว่าการรองรับนิพจน์ทั่วไปใน lua ถูก จำกัด

Lua จะมีขอบเขตคำศัพท์ JavaScript มีขอบเขตฟังก์ชันเท่านั้น ใน Mozilla และ Rhino yo สามารถใช้ 'let' แทน 'var' และได้รับขอบเขตคำศัพท์ที่เหมาะสม แต่ยังไม่สามารถพกพาได้
Javier

1
ไลบรารีสตริงมาตรฐานของ Lua มีฟังก์ชันการจับคู่รูปแบบที่ จำกัด แต่ยังมี LPEG (รวมถึงไลบรารี) ซึ่งให้ระบบการจับคู่ที่มีประสิทธิภาพมากขึ้นและใช้งานได้ง่ายสำหรับไวยากรณ์แบบเต็ม
Javier

ฉันระบุว่า LUA มีขอบเขตคำศัพท์ที่ "ดีกว่า" แล้ว javascript ไม่ใช่ว่าไม่มีเลย
กระวนกระวายใจ

1
LPEG เป็นไลบรารีเพิ่มเติมซึ่งหมายความว่าการสนับสนุน regex หลักนั้น จำกัด สำหรับฉัน
กระวนกระวายใจ

มีข้อ จำกัด อยู่บ้างระหว่างปุ่มสตริงและปุ่มตัวเลขการใช้ทั้งสองอย่างในตารางเดียวกันจะยุ่งเหยิงอย่างรวดเร็วเนื่องจาก # ส่งคืนความยาวของตารางไม่ใช่ตามจำนวนดัชนีที่มีตัวเลขซึ่งจะขัดแย้งกับรายการพจนานุกรมใด ๆ (การจัดทำดัชนีศูนย์หลังจากแจกแจง table indexes)
Weeve Ferrelaine

3

ฉันชอบคำถามนี้และคำตอบที่ให้ไว้ เหตุผลเพิ่มเติมที่ทั้งสองภาษาดูเหมือนไม่เหมือนกันสำหรับฉัน:

ทั้งสองกำหนดฟังก์ชันให้กับตัวแปรสามารถสร้างฟังก์ชันได้ทันทีและกำหนดการปิด


1

Lua และ JavaScript เป็นภาษาพื้นฐานต้นแบบ


1
นี่คือความคล้ายคลึงกันที่ชัดเจนระหว่างสองภาษานี้และการใช้ตาราง / แฮชเป็นประเภทข้อมูลหลัก หากคุณต้องการพัฒนาโปรแกรม Javascript โดยใช้สำนวนคุณจะใช้แนวทางเดียวกับที่คุณทำใน Lua คุณจะไม่ทำเช่นเดียวกันในภาษาอื่น ๆ ของนิวยอร์ก (เว้นแต่ว่าจะเป็นภาษาที่อิงตามการสืบทอดของ Protype และตาราง) นี่คือความคล้ายคลึงกันอย่างมาก ส่วนที่เหลือรายละเอียดเกี่ยวกับไวยากรณ์รองและอื่น ๆ นั้นค่อนข้างอวดดีในการเปรียบเทียบ
Alex Gian

1
ความแตกต่างที่สำคัญคือ Jaavscript ไม่รองรับโครูทีนไม่ได้ใช้คู่กับ C อย่างแน่นหนาและไม่เหมาะเป็นภาษาฝังตัว (มีโปรแกรมไมโครคอนโทรลเลอร์กี่ตัวใน Javascript) Javascript ยังเป็นระเบียบกว่าด้วย gotchas และ WAT แบบดั้งเดิมจำนวนมาก ( destroyallsoftware.com/talks/wat ) - ตั้งแต่ 1:40 Lua มีระเบียบวินัยที่ดีของชาวสปาร์ตัน แน่นอนว่า Javascript นั้นแข็งแกร่งมากในเบราว์เซอร์
Alex Gian

1

การทดสอบแสดงให้เห็นว่า Javascript ปัจจุบันยังส่งคืนอ็อบเจ็กต์หรืออย่างน้อยก็สตริงจากนิพจน์ตรรกะเช่น lua ทำ:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.