자바 스크립트와 Lua의 미묘한 차이점


121

저는 JavaScript를 아주 좋아합니다. 너무 우아합니다 (백그라운드에서 한숨을 쉬는 사랑에 빠진 팬보이의 조용한 소리를 상상해보세요).

그래서 최근에 저는 löve2d 프레임 워크 (nice!) 를 통해 Lua와 놀았습니다 . 그리고 Lua도 훌륭하다고 생각합니다. 제가보기에이 두 언어는 매우 유사합니다.

다음과 같은 명백한 차이점이 있습니다.

  • 통사론
  • 문제 영역
  • 도서관
  • 유형 (약간)

그러나 더 미묘한 것은 무엇입니까? Lua에서 약간 다르게 작동하는 JavaScript 코더가 당연하게 생각하는 것이 있습니까? 한 언어의 숙련 된 코더가 다른 언어를 시도하는 경우 명확하지 않을 수있는 함정이 있습니까?

예를 들어, Lua에서 배열과 해시는 분리되지 않습니다 (테이블 만 있음). JavaScript에서는 숫자 배열과 해시 된 객체입니다. 음, 이것은 더 명백한 차이점 중 하나입니다.

그러나 변수 범위, 불변성 또는 이와 비슷한 차이점이 있습니까?


8
전체 비교를 찾고 우연히 여기에 도착한
Tao

시작하기 위해 알아야 할 모든 차이점을 설명하는 3 부작 시리즈입니다. oreilly.com/learning/…
charAt

답변:


189

더 많은 차이점 :

  • Lua코 루틴 을 기본적으로 지원합니다 .
    • 업데이트 : JS는 이제 생성기 내부에 yield 키워드를 포함하여 코 루틴을 지원합니다.
  • Lua 비교 연산자에 대해 유형간에 변환하지 않습니다 . JS에서, 단지 ===!==저글링 입력하지 마십시오.
  • Lua 에는 지수 연산자 ( ^)가 있습니다. JS 는 그렇지 않습니다. JS는 원계 조건 연산자 (포함한 다양한 연산자 사용 ?:VS를 and/or5.3 비트 연산자 (현재의)과 &, |등 대 메타 메소드 ).
    • 업데이트 : JS에는 이제 지수 연산자가 **있습니다.
  • JS 에는 증가 / 감소, 유형 연산자 ( typeofinstanceof), 추가 할당 연산자 및 추가 비교 연산자가 있습니다.
  • 에서는 JS==, ===, !=!==운영자가보다 낮은 우선 순위로되어 >, >=, <, <=. Lua에서 모든 비교 연산자는 동일한 우선 순위 입니다.
  • Lua꼬리 호출을 지원 합니다 .
  • Lua변수 목록에 대한 할당을 지원 합니다 . 아직 Javascript 에서는 표준이 아니지만 Mozilla의 JS 엔진 (및 Opera의 경우 어느 정도)은 " 구조화 할당 " 이라는 이름으로 JS 1.7 (Firefox 2의 일부로 사용 가능) 이후 유사한 기능을 지원했습니다 . JS의 Destructuring은 함수 정의 및 호출루프 이니셜 라이저 와 같은 할당 이외의 컨텍스트에서 사용할 수 있기 때문에 더 일반적 입니다. Destructuring 할당 은 한동안 ECMAScript (Javascript 뒤에있는 언어 표준)에 추가로 제안되었습니다.
    • 업데이트 : Destructuring (및 Destructuring Assignment)은 이제 ECMAScript 사양의 일부이며 이미 많은 엔진에서 구현되었습니다.
  • Lua 에서는 연산자오버로드 할 수 있습니다 .
  • 루아 , 당신과 환경을 조작 할 수 있습니다 getfenvsetfenv 루아 5.1 또는 _ENV에서 루아 5.25.3 .
  • 에서는 JS , 모든 기능은 가변이다. 에 루아 , 기능해야 명시 적으로 가변 인자로 선언 .
  • Foreach객체 속성 에 대한 JS 루프 에서 . foreach 문루아 (키워드를 사용 for) 반복자를 통해 루프 더 일반적이다.
    • 업데이트 : JS에는 이제 Iterables 도 있으며, 그중 많은 것들이 Array. 이것들은 for...of구문 으로 반복 될 수 있습니다 . 일반 객체의 경우 자체 반복기 함수를 구현할 수 있습니다. 이것은 Lua에 훨씬 더 가깝게 만듭니다.
  • JS에는 전역 및 기능 범위가 있습니다. Lua 에는 글로벌 및 블록 범위가 있습니다. 제어 구조 (예를 들면 if, for, while) 신규 도입 블록을 .

    • 범위 지정 규칙의 차이로 인해 외부 변수에 대한 클로저 참조 (Lua 용어로 "upvalue"라고 함)는 Lua와 Javascript 에서 다르게 처리 될 수 있습니다 . 이것은 루프의 클로저에서for 가장 일반적으로 경험하며 일부 사람들을 놀라게합니다. 에서는 자바 하는 본문 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)

      결과적으로 개별 반복에서 정의 된 함수는 참조 된 각 루프 변수에 대해 서로 다른 upvalue를 갖습니다. Lua에서 클로저 구현에 대한 Nicolas Bola의 답변을 참조하십시오 . 및 " 루프 변수에 대한 클로저의 올바른 의미는 무엇입니까? "및 " 일반에 대한 의미 ".

      업데이트 : JS에는 이제 블록 범위가 있습니다. 블록 범위로 정의 let되거나 const존중되는 변수 .

  • JS의 정수 리터럴은 8 진수 일 수 있습니다.
  • JS 에는 명시적인 유니 코드 지원이 있으며 내부적으로 문자열은 UTF-16으로 인코딩됩니다 (따라서 바이트 쌍의 시퀀스). 다양한 내장 JavaScript 함수는 "pâté".toUpperCase()( "PÂTÉ") 와 같은 유니 코드 데이터를 사용 합니다. Lua 5.3 이상에는 문자열 리터럴 (JavaScript 코드 포인트 이스케이프 시퀀스와 동일한 구문 사용)의 유니 코드 코드 포인트 이스케이프 시퀀스와 UTF-8 인코딩에utf8 대한 기본 지원을 제공 하는 내장 라이브러리가 있습니다.(예 : 코드 포인트를 UTF-8로 인코딩하고 UTF-8을 코드 포인트로 디코딩하고, 문자열의 코드 포인트 수를 가져오고, 코드 포인트를 반복). Lua의 문자열은 개별 바이트의 시퀀스이며 모든 인코딩 또는 임의의 이진 데이터에 텍스트를 포함 할 수 있습니다. Lua에는 유니 코드 데이터를 사용하는 내장 함수가 없습니다. 의 동작은 string.upperC 로케일 에 따라 다릅니다.
  • 루아not, or, and키워드 대신에 사용하는 JS!, ||, &&.
  • Lua~="같지 않음"을 사용 하는 반면 JS!==. 예를 들면 if foo ~= 20 then ... end.
  • Lua 5.3 이상 ~은 바이너리 비트 XOR에 사용 되는 반면 JS^.
  • 에서는 루아 , 값 (단 중 어느 타입 nilNaN) 인덱스 테이블을 사용할 수있다. 에서 자바 스크립트 (기호 제외) 모든 문자열이 아닌 유형의 인덱스에 객체를 사용하기 전에 문자열로 변환됩니다. 예를 들어, 다음 코드 평가 후,의 값이 obj[1]될 것입니다 "string one"하지만, 자바 스크립트에 "number one"루아 : obj = {}; obj[1] = "number one"; obj["1"] = "string one";.
  • 에서 JS , 과제는 식으로 처리되지만,에 루아 그들은하지 않습니다. 따라서, JS는 조건에 할당 할 수 있습니다 if, while그리고 do while문을하지만, 루아에서하지 않습니다 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에서 논리 연산자 (and, or)는 인수 중 하나를 반환합니다. 모든 함수는 여러 매개 변수로 호출 할 수 있습니다. 하지만 필요한 수로 조정됩니다 (... '추가 인수'를 사용하지 않는 한)
Javier

1
@RCIX : luaconf.h 참조 (Lua 5.2에서는 lparser.c 및 llimits.h). Lua 5.1 및 Lua 5.2에서 최대 로컬 값 / 함수 = 200. Max upvalues ​​/ function = Lua 5.1에서 60, Lua 5.2에서 255 (그리고이 계수에는 함수 내부에서 생성 된 "상속 된"클로저에 의해 "상속 된"upvalue도 포함됩니다.
dubiousjim

8
1 기반 배열을 목록에 추가 할 수 있다고 생각합니다. 익숙하지 않을 때는 꽤 짜증이 날 수 있습니다.

2
Lua에서는 nil과 false 만 거짓입니다. 예를 들어 0은 Lua에서는 진실이지만 js에서는 그렇지 않습니다. 유니 코드 지원 정보 : Lua 5.3은 명시적인 UTF-8 지원을 추가하고, 이전 Lua 버전은 문자열에있는 UTF-8 버퍼에 친숙합니다 (예 : 문자열 검색 패턴에서 유니 코드를 사용할 수 있음). UTF-8의 JS 지원은 V8이 내부적으로 오래된 16 비트 표현을 사용하기 때문에 완벽하지 않으므로 유니 코드 문자열은 좋은 UTF-8에서 필요하지 않은 (놀라운!) 서로 게이트 쌍으로 끝날 수 있습니다. Lua에서는 발생하지 않습니다).
타일러

4
이 목록이 마음에 들었지만 어떻게 미묘한 버그를 ~=유발할 수 있는지 모르겠습니다 . 구문 오류 를 유발할 수 있지만 전혀 미묘하지는 않습니다.
kikito

12

최소한 한 번은 눈에 띄는 몇 가지 미묘한 차이점 :

  • 같지 않음은 ~=Lua에서 철자 됩니다. JS에서는!=
  • Lua 배열은 1부터 시작 합니다. 첫 번째 인덱스는 0이 아니라 1입니다.
  • 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는 원하지 않는 모든 것을 지속적으로 흘립니다.
Javier

3
+1. 둘 다 스크립팅에 사용된다는 사실을 제외하고는 (너무 명백한) 사실을 제외하고는 그들이 어떻게 비슷한 지 전혀 알지 못합니다.
Sasha Chedygov

13
-1 (내가 할 수 있다면) 그들은 언어 디자인면에서 매우 유사합니다. Lua는 단순히 더 많은 기능을 가지고 있으며 더 작습니다 (더 빠릅니다?). 언어 디자인과 구현 선택을 혼동한다고 생각합니다.
jpc

예, 둘 다 프로토 타입 OOP입니다 ( prototype루아 테이블이 정확히 그렇다는 사실에도 불구하고 키워드 또는 객체 이름 지정 객체를 사용하여 명시 적으로 지정 되지 않은 경우 에도), 전통적인 의미에서 기능하지 않음에도 불구하고 일류 시민으로서의 기능 (불변성 선언적 개발 등)
보얀 마코 빅

2
물론 구문상의 차이가 있으며 표면적으로 보면 언어가 다르다는 결론을 내릴 수 있습니다. 그러나 정확히 같은 주요 데이터 유형 (객체 / 테이블)과 (뭔가 클래스와 inherritance 구현 같은 방식으로 필요에 매우 몇 가지 다른 언어 공유)를 놀라 울 정도로 가까운 정신을하게합니다. 사소하지 않은 JS 프로그램의 디자인은 Lua 프로그램의 디자인과 거의 동일합니다.
Alex Gian 2017

7

자바 스크립트 배열과 객체는 생각보다 가깝습니다. 배열 표기법을 사용하여 둘 중 하나의 요소를 가져올 수 있으며 배열에 숫자가 아닌 인덱스를 추가 할 수 있습니다. 개별 배열 요소는 무엇이든 포함 할 수 있으며 배열은 희소 할 수 있습니다. 그들은 거의 동일한 사촌입니다.


1
동일한 사촌을 가질 수 있습니까?
jameshfisher 2011-06-22

그것들은 동일한 데이터 구조이고 유일한 차이점은 타입 설명자이므로 구분할 수 있습니다.
Lilith River

5
보다 정확한 진술은 다음과 같습니다. 배열은 "길이"멤버의 특별한 동작을 가진 객체입니다.
tzenes

@eegg : 물론 이죠, Cathy와 Patty .
outis

3

내 머릿속에서

루아 ...

  1. 지원 코 루틴
  2. 테이블의 키로 문자열 / 숫자에만 제한이 없습니다. 모든 것이 작동합니다.
  3. 오류 처리가 다소 어색합니다. 아무것도 처리하지 않거나 pcall을 사용하십시오 . 메서드를
  4. 어휘 범위의 차이점과 Lua가 더 나은 것을 읽은 것 같습니다.
  5. 루아의 정규 표현식 지원이 제한되어 있습니다.

루아는 않습니다 어휘 범위를 가지고있다. JavaScript에는 함수 범위 만 있습니다. 음, Mozilla와 Rhino에서는 이제 'var'대신 'let'을 사용하여 적절한 어휘 범위를 얻을 수 있습니다. 하지만 아직 이식성이 없습니다.
Javier

1
Lua의 표준 문자열 라이브러리에는 제한된 패턴 일치 기능이 포함되어 있습니다. 하지만 훨씬 더 강력한 매칭 시스템을 제공하고 전체 문법에 쉽게 사용할 수있는 LPEG (또한 라이브러리)도 있습니다.
Javier

나는 LUA가 "더 나은"어휘 범위를 가지고 있고 자바 스크립트가 아니라고 말했다.
jitter

1
LPEG는 핵심 정규식 지원이 나에게 제한됨을 의미하는 추가 라이브러리입니다
지터

문자열 키와 숫자 키 사이에는 약간의 제한이 있습니다. 동일한 테이블에서 둘 다 사용하면 #이 번호가 매겨진 인덱스의 양이 아닌 테이블 길이를 반환하므로 모든 사전 항목과 충돌합니다 (열거 후 nil 인덱싱). 테이블 인덱스)
Weeve Ferrelaine

3

이 질문과 제공된 답변이 마음에 들었습니다. 두 언어가 나에게 더 비슷해 보이는 추가 이유 :

둘 다 변수에 함수를 할당하고, 즉시 함수를 빌드하고, 클로저를 정의 할 수 있습니다.


1

Lua와 JavaScript는 모두 프로토 타입 기본 언어입니다.


1
이것은 두 언어 사이의 명백한 유사성이며 기본 데이터 유형으로 테이블 / 해시를 사용하는 것입니다. Javascript 프로그램을 관용적으로 개발한다면 Lua에서와 거의 동일한 접근 방식을 취할 것입니다. 다른 언어에서는 동일하지 않습니다 (프로 타입 상속 및 테이블에 기반한 언어가 아닌 경우). 이것은 매우 유사합니다. 나머지, 사소한 구문 등에 대한 세부 사항은 비교해 보면 꽤 현명합니다.
Alex Gian

1
중요한 차이점은 Jaavscript가 코 루틴을 지원하지 않고 C와 밀접하게 결합되어 있지 않으며 실제로 임베디드 언어로 적합하지 않다는 것입니다. (Javascript로 프로그래밍 된 마이크로 컨트롤러는 몇 개입니까?) Javascript는 1:40부터 수많은 레거시 문제와 WAT ( destroyallsoftware.com/talks/wat )로 인해 훨씬 ​​더 복잡 합니다. Lua는 예쁜 스파르타 규율을 부과했습니다. 물론 Javascript는 브라우저에서 매우 강력합니다.
Alex Gian

1

테스트 결과 현재 Javascript는 객체 또는 최소한 lua와 같은 논리 표현식의 문자열도 반환합니다.

function nix(){
    alert(arguments[0]||"0");
} 
nix();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.