sự khác biệt tinh tế giữa JavaScript và Lua [đóng]


121

Tôi chỉ đơn giản là yêu thích JavaScript. Nó rất thanh lịch (hãy tưởng tượng âm thanh yên tĩnh của fanboy lovestruck thở dài trong nền).

Vì vậy, gần đây tôi đã chơi với Lua thông qua khuôn khổ löve2d (thật tuyệt!) - và tôi nghĩ Lua cũng rất tuyệt. Theo cách tôi thấy, hai ngôn ngữ đó rất giống nhau.

Có sự khác biệt rõ ràng, như

  • cú pháp
  • miền vấn đề
  • thư viện
  • các loại (một chút)

nhưng cái nào tinh tế hơn? Có điều gì mà một lập trình viên JavaScript sẽ cho là hiển nhiên hoạt động trong Lua chỉ hơi khác một chút không? Có bất kỳ cạm bẫy nào có thể không rõ ràng đối với lập trình viên có kinh nghiệm của một ngôn ngữ đang thử ngôn ngữ kia không?

Ví dụ: trong Lua, mảng và băm không tách biệt (chỉ có bảng) - trong JavaScript, chúng là Mảng số và Đối tượng được băm. Chà, đây là một trong những điểm khác biệt rõ ràng hơn.

Nhưng có sự khác biệt nào về phạm vi biến, tính bất biến hoặc những thứ tương tự như thế này không?


8
Đối với những người, như tôi, người đang tìm kiếm một so sánh tổng thể và tình cờ kết thúc ở đây, sau đây là một cái nhìn tổng quan tốt đẹp: phrogz.net/lua/LearningLua_FromJS.html
Tao

Đây là một loạt ba phần giải thích tất cả những điểm khác biệt mà bạn cần biết để bắt đầu: oreilly.com/learning/…
charAt vào

Câu trả lời:


189

Một số điểm khác biệt:

  • Lua có hỗ trợ bản địa cho coroutines .
    • CẬP NHẬT : JS bây giờ chứa từ khóa lợi nhuận bên trong trình tạo, hỗ trợ nó cho các quy trình.
  • Lua không chuyển đổi giữa các kiểu cho bất kỳ toán tử so sánh nào. Trong JS, chỉ ===!==không gõ tung hứng.
  • Lua có một toán tử lũy thừa ( ^); JS không. JS sử dụng các nhà khai thác khác nhau, bao gồm các nhà điều hành có điều kiện ternary ( ?:vs and/or), và, như 5,3, toán tử Bitwise ( &, |vv vs metamethods ).
    • CẬP NHẬT : JS bây giờ có toán tử lũy thừa **.
  • JS có các toán tử tăng / giảm, toán tử kiểu ( typeofinstanceof), toán tử gán bổ sung và toán tử so sánh bổ sung.
  • Trong JS , các ==, ===, !=!==nhà khai thác được ưu tiên thấp hơn >, >=, <, <=. Trong Lua, tất cả các toán tử so sánh đều được ưu tiên như nhau .
  • Lua hỗ trợ các cuộc gọi đuôi .
  • Lua hỗ trợ gán cho một danh sách các biến . Mặc dù nó chưa phải là tiêu chuẩn trong Javascript , nhưng công cụ JS của Mozilla (và của Opera, ở một mức độ nào đó) đã hỗ trợ một tính năng tương tự kể từ JS 1.7 (có sẵn như một phần của Firefox 2) dưới tên " phân công hủy cấu trúc ". Cấu trúc hủy trong JS tổng quát hơn, vì nó có thể được sử dụng trong các ngữ cảnh khác với việc gán, chẳng hạn như định nghĩa hàm & lời gọibộ khởi tạo vòng lặp . Chuyển nhượng cơ cấu đã được đề xuất bổ sung cho ECMAScript (tiêu chuẩn ngôn ngữ đằng sau Javascript) trong một thời gian.
    • CẬP NHẬT : Tái cấu trúc (và gán cấu trúc hủy) hiện là một phần của thông số kỹ thuật cho ECMAScript - đã được triển khai trong nhiều công cụ.
  • Trong Lua , bạn có thể nạp chồng các toán tử .
  • Trong Lua , bạn có thể thao tác môi trường với getfenvsetfenv trong Lua 5.1 hoặc _ENVtrong Lua 5.25.3 .
  • Trong JS , tất cả các hàm đều khác nhau. Trong Lua , các hàm phải được khai báo rõ ràng dưới dạng biến thể .
  • Foreachtrong JS lặp qua các thuộc tính đối tượng. Foreach in Lua (sử dụng từ khóa for) lặp lại trên các trình lặp và tổng quát hơn.
    • CẬP NHẬT : JS hiện cũng có các tệp lặp lại, nhiều phần trong số đó được tích hợp vào cấu trúc dữ liệu thông thường mà bạn mong đợi, chẳng hạn như Array. Chúng có thể được lặp lại với for...ofcú pháp. Đối với các Đối tượng thông thường, người ta có thể triển khai các chức năng trình vòng lặp của riêng chúng. Điều này mang nó đến gần Lua hơn nhiều.
  • JS có phạm vi toàn cầu và chức năng. Luaphạm vi toàn cầu và khối . Cấu trúc điều khiển (ví dụ if, for, while) giới thiệu mới khối .

    • Do sự khác biệt về quy tắc xác định phạm vi, việc tham chiếu đến một biến bên ngoài (được gọi là "upvalues" trong cách nói của Lua) có thể được xử lý khác nhau trong Lua và trong Javascript . Điều này thường gặp nhất với việc đóng trong forvòng lặp và khiến một số người ngạc nhiên. Trong Javascript , phần thân của forvòng lặp không giới thiệu phạm vi mới, vì vậy bất kỳ hàm nào được khai báo trong phần thân của vòng lặp đều tham chiếu đến các biến bên ngoài giống nhau . Trong Lua, mỗi lần lặp của forvòng lặp sẽ tạo ra các biến cục bộ mới cho mỗi biến vòng lặp.

      local i='foo'
      for i=1,10 do
        -- "i" here is not the local "i" declared above
        ...
      end
      print(i) -- prints 'foo'

      Đoạn mã trên tương đương với:

      local i='foo'
      do
        local _i=1
        while _i<10 do
          local i=_i
          ...
          _i=_i+1
        end
      end
      print(i)

      Do đó, các hàm được xác định trong các lần lặp riêng biệt có giá trị nâng cao khác nhau cho mỗi biến vòng lặp được tham chiếu. Xem thêm câu trả lời của Nicolas Bola về Thực hiện đóng cửa trong Lua? và " Ngữ nghĩa chính xác của một bao đóng trên một biến vòng lặp là gì? " và " Ngữ nghĩa của Chung cho ".

      CẬP NHẬT : JS hiện có phạm vi khối. Các biến được xác định với lethoặc consttôn trọng phạm vi khối.

  • Các ký tự số nguyên trong JS có thể ở dạng bát phân.
  • JS có hỗ trợ Unicode rõ ràng và các chuỗi bên trong được mã hóa bằng UTF-16 (vì vậy chúng là chuỗi các cặp byte). Các hàm JavaScript tích hợp sẵn khác nhau sử dụng dữ liệu Unicode, chẳng hạn như "pâté".toUpperCase()( "PÂTÉ"). Lua 5.3 trở lên có chuỗi thoát điểm mã Unicode trong chuỗi ký tự (với cú pháp giống như chuỗi thoát điểm mã JavaScript) cũng như utf8thư viện tích hợp, cung cấp hỗ trợ cơ bản cho mã hóa UTF-8(chẳng hạn như mã hóa điểm mã thành UTF-8 và giải mã UTF-8 thành điểm mã, nhận số điểm mã trong một chuỗi và lặp qua các điểm mã). Các chuỗi trong Lua là chuỗi các byte riêng lẻ và có thể chứa văn bản trong bất kỳ mã hóa hoặc dữ liệu nhị phân tùy ý nào. Lua không có bất kỳ chức năng tích hợp nào sử dụng dữ liệu Unicode; hành vi của string.upperphụ thuộc vào ngôn ngữ C.
  • Trong Lua , các not, or, andtừ khóa được sử dụng ở vị trí của JS s' !, ||, &&.
  • Lua sử dụng ~=cho "không bằng", trong khi JS sử dụng !==. Ví dụ if foo ~= 20 then ... end,.
  • Lua 5.3 trở lên sử dụng ~cho XOR bitwise nhị phân, trong khi JS sử dụng ^.
  • Trong Lua , bất kỳ loại giá trị nào (ngoại trừ nilNaN) đều có thể được sử dụng để lập chỉ mục bảng. Trong JavaScript , tất cả các loại không phải chuỗi (ngoại trừ Biểu tượng) đều được chuyển đổi thành chuỗi trước khi được sử dụng để lập chỉ mục một đối tượng. Ví dụ, sau khi đánh giá của các mã sau đây, giá trị của obj[1]sẽ "string one"trong JavaScript, nhưng "number one"trong Lua: obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • Trong JS , các phép gán được coi là biểu thức, nhưng trong Lua thì không. Do đó, JS cho phép tập trong điều kiện if, whiledo whilebáo cáo, nhưng Lua không trong if, whilerepeat untilbáo cáo. Ví dụ: if (x = 'a') {}là JS hợp lệ, nhưng if x = 'a' do endlà Lua không hợp lệ.
  • Lua có đường cú pháp kê khai biến khối chức năng-scoped, chức năng mà là lĩnh vực, và các phương pháp ( local function() end, function t.fieldname() end, function t:methodname() end). JS khai báo những điều này với một dấu bằng ( let funcname = function optionalFuncname() {}, objectname.fieldname = function () {}).

6
trong Lua, các toán tử logic (và, hoặc) trả về một trong các đối số. tất cả các hàm có thể được gọi với bất kỳ số lượng tham số nào; nhưng được điều chỉnh đến số lượng cần thiết (trừ khi bạn sử dụng ... 'thêm args')
Javier

1
@RCIX: xem luaconf.h (và trong Lua 5.2, cả lparser.c và llimits.h). Giá trị cục bộ tối đa / hàm = 200 trong Lua 5.1 và Lua 5.2. Các giá trị nâng cấp tối đa / hàm = 60 trong Lua 5.1, 255 trong Lua 5.2 (và số lượng này cũng bao gồm các giá trị nâng cao "được kế thừa bởi" các bao đóng được tạo bên trong hàm).
dubiousjim

8
Tôi nghĩ rằng bạn có thể thêm các mảng dựa trên 1 vào danh sách, nó có thể khá khó chịu khi bạn không quen với nó.
Yann

2
Chỉ nil và false là sai trong Lua - vì vậy, ví dụ, 0 là true trong Lua nhưng không phải trong js. Về hỗ trợ Unicode: Lua 5.3 bổ sung một số hỗ trợ UTF-8 rõ ràng và các phiên bản Lua cũ hơn thân thiện với bộ đệm UTF-8 được tổ chức trong chuỗi (ví dụ: bạn có thể sử dụng Unicode trong các mẫu tìm kiếm chuỗi). Hỗ trợ Js của UTF-8 không hoàn hảo vì V8 bên trong sử dụng biểu diễn 16 bit cũ, vì vậy các chuỗi unicode của bạn có thể kết thúc với (thật bất ngờ!) Các cặp thay thế không cần thiết trong UTF-8 tốt (và đã thắng 'không xảy ra ở Lua).
Tyler

4
Tôi thích danh sách này, nhưng tôi không thấy làm thế nào ~=có thể kích động các lỗi tinh vi . Nó có thể gây ra các lỗi cú pháp , nhưng chúng không hề tinh tế.
kikito

12

Một vài điểm khác biệt nhỏ sẽ khiến bạn ít nhất một lần nhận ra:

  • Không bằng được đánh vần ~=trong Lua. Trong JS nó là!=
  • Mảng Lua dựa trên 1 - chỉ số đầu tiên của chúng là 1 thay vì 0.
  • Lua yêu cầu dấu hai chấm thay vì dấu chấm để gọi các phương thức đối tượng. Bạn viết a:foo()thay vì a.foo()

bạn có thể sử dụng dấu chấm nếu muốn, nhưng phải chuyển selfbiến một cách rõ ràng. a.foo(a)trông hơi rườm rà. Xem Lập trình trong Lua để biết chi tiết.


5
sử dụng cho các chú thích làm cho nó có vẻ như a.foo()đã chết xD
DarkWiiPlayer

11

Thành thật mà nói, sẽ dễ dàng hơn nếu liệt kê những thứ phổ biến đối với Javascript và Lua hơn là liệt kê những điểm khác biệt. Cả hai đều là ngôn ngữ kịch bản được nhập động, nhưng đó là chừng mực bạn có thể thực sự làm được. Chúng có cú pháp hoàn toàn khác nhau, mục tiêu thiết kế ban đầu khác nhau, phương thức hoạt động khác nhau (Lua luôn được biên dịch thành bytecode và chạy trên Lua VM, Javascript thay đổi), danh sách này cứ tiếp tục.


8
chắc chắn rồi. các mục tiêu rất khác nhau bao gồm ưu tiên cao để có một ngôn ngữ trong sáng. Javascript có rất nhiều hành trang lịch sử, Lua liên tục loại bỏ bất cứ điều gì không mong muốn.
Javier

3
+1. Tôi thậm chí không thấy chúng giống nhau như thế nào, ngoại trừ thực tế là cả hai đều được sử dụng để viết kịch bản (điều này quá rõ ràng).
Sasha Chedygov

13
-1 (nếu tôi có thể) Chúng rất giống nhau về mặt thiết kế ngôn ngữ. Lua chỉ đơn giản là có nhiều tính năng hơn và nhỏ hơn (cũng nhanh hơn?). Tôi nghĩ rằng bạn nhầm lẫn giữa thiết kế ngôn ngữ với các lựa chọn triển khai.
jpc

Vâng, cả hai đều là OOP nguyên mẫu (ngay cả khi nó không được tuyên bố rõ ràng bằng cách sử dụng từ khóa prototypehoặc đặt tên cho các đối tượng, mặc dù thực tế đó chính xác là bảng lua), với các chức năng như công dân hạng nhất mặc dù không hoạt động theo nghĩa truyền thống (tính bất biến , phát triển khai báo, v.v.),
Bojan Markovic

2
Chắc chắn, có sự khác biệt về cú pháp và nếu nhìn bề ngoài, bạn có thể kết luận các ngôn ngữ là khác nhau. Tuy nhiên, việc có cùng một kiểu dữ liệu chính (đối tượng / bảng) và cùng một cách triển khai các lớp và kế thừa (điều mà rất ít ngôn ngữ khác chia sẻ) làm cho chúng gần gũi một cách đáng kinh ngạc. Thiết kế của chương trình JS không tầm thường sẽ khá giống với thiết kế của chương trình Lua.
Alex Gian

7

Các mảng và đối tượng JavaScript gần gũi hơn bạn tưởng. Bạn có thể sử dụng ký hiệu mảng để lấy các phần tử của một trong hai và bạn có thể thêm các chỉ số không phải số vào mảng. Các phần tử mảng riêng lẻ có thể chứa bất kỳ thứ gì và mảng có thể thưa thớt. Họ là anh em họ gần giống hệt nhau.


1
Một người có thể có anh em họ giống hệt nhau?
jameshfisher

Chúng có cấu trúc dữ liệu giống nhau, điểm khác biệt duy nhất là bộ mô tả kiểu để bạn có thể phân biệt chúng.
Sông Lilith

5
Một phát biểu chính xác hơn sẽ là: Mảng là các Đối tượng có hành vi đặc biệt của thành viên "độ dài" của chúng.
tzenes

@eegg: chắc chắn rồi, Cathy và Patty .
outis

3

Off đỉnh đầu của tôi

Lua ...

  1. hỗ trợ coroutines
  2. không hạn chế chỉ chuỗi / số làm khóa cho bảng. Làm tất cả mọi việc.
  3. việc xử lý lỗi hơi vụng về. Hoặc bạn không xử lý bất cứ điều gì hoặc sử dụng phương pháp pcall
  4. Tôi nghĩ rằng tôi đã đọc vài điều về sự khác biệt trong phạm vi từ vựng và Lua có cái hay hơn.
  5. Nếu tôi nhớ chính xác thì hỗ trợ biểu thức chính quy trong lua bị hạn chế

Lua không có phạm vi từ vựng. JavaScript chỉ có phạm vi chức năng. tốt, trong Mozilla và Rhino, bây giờ bạn có thể sử dụng 'let' thay vì 'var' và có được phạm vi từ vựng thích hợp; nhưng nó chưa phải là di động.
Javier

1
Thư viện chuỗi tiêu chuẩn của Lua bao gồm các hàm đối sánh mẫu giới hạn; nhưng cũng có LPEG (cũng là một thư viện), mang đến một hệ thống đối sánh mạnh mẽ hơn nhiều, dễ dàng sử dụng cho một ngữ pháp đầy đủ.
Javier

Tôi đã nói rằng LUA có phạm vi từ vựng "tốt hơn" thì javascript không phải là nó không có bất kỳ.
jitter

1
LPEG là một thư viện bổ sung mà có nghĩa là hỗ trợ lõi regex được giới hạn với tôi
jitter

có một số hạn chế giữa các phím chuỗi và phím số, việc sử dụng cả hai trong cùng một bảng sẽ trở nên lộn xộn rất nhanh, vì # trả về độ dài bảng chứ không phải theo số lượng chỉ mục được đánh số, điều này sẽ xung đột với bất kỳ mục nhập từ điển nào (lập chỉ mục nil sau khi liệt kê bảng chỉ mục)
Weeve Ferrelaine

3

Tôi thích câu hỏi này và câu trả lời được cung cấp. Các lý do khác khiến hai ngôn ngữ có vẻ giống nhau hơn là không giống với tôi:

Cả hai đều gán hàm cho các biến, có thể xây dựng các hàm một cách nhanh chóng và xác định các bao đóng.


1

Lua và JavaScript đều là ngôn ngữ cơ sở nguyên mẫu.


1
Đây là sự giống nhau rõ ràng giữa hai ngôn ngữ, điều này và việc chúng sử dụng bảng / băm làm kiểu dữ liệu chính. Nếu bạn phát triển một chương trình Javascript một cách thành ngữ, bạn sẽ áp dụng cách tiếp cận tương tự như cách bạn làm trong Lua. Bạn sẽ không làm điều tương tự với một ngôn ngữ khác (trừ khi đó là một ngôn ngữ dựa trên bảng kế thừa kiểu và bảng). Đây là một điểm tương đồng rất lớn. Phần còn lại, các chi tiết về cú pháp nhỏ, v.v. so sánh khá phức tạp.
Alex Gian

1
Sự khác biệt quan trọng là Jaavscript không hỗ trợ coroutines, không kết hợp chặt chẽ với C và không thực sự phù hợp như một ngôn ngữ nhúng. (Có bao nhiêu vi điều khiển được lập trình trong javascript?) Javascript cũng là nhiều Messier, với vô số gotchas di sản và wats ( destroyallsoftware.com/talks/wat ) - từ 01:40. Lua đã bị áp dụng một hình thức kỷ luật khá nghiêm khắc của Spartan. Javascript, tất nhiên, rất mạnh trong trình duyệt.
Alex Gian

1

Một bài kiểm tra cho thấy rằng Javascript hiện tại cũng trả về các đối tượng, hoặc ít nhất là các chuỗi từ các biểu thức logic như lua:

function nix(){
    alert(arguments[0]||"0");
} 
nix();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.