파이썬의 줄 바꿈 처리는 JavaScript의 자동 세미콜론과 어떻게 다릅니 까?


41

Javascript에는 자동 세미콜론 삽입이라는 기능이 있습니다. 기본적으로 파서에 잘못된 토큰이 있고 그 이전의 마지막 토큰이 줄 바꿈 인 경우 파서는 줄 바꿈이있는 곳에 세미콜론을 삽입합니다. 이렇게하면 기본적으로 세미콜론없이 모든 자바 스크립트 코드를 작성할 수 있지만 대부분 반환 단어가 있고 새 줄에 반환하려는 값이있는 경우 몇 가지 중요한 경우를 알고 있어야합니다.

function test(){
    // This will return 'undefined', because return is a valid statement
    // and  "john" is a valid statement on its own.
    return 
          "john"
}

이 문제로 인해 '자동 세미콜론 삽입은 악하다', '항상 자바 스크립트에서 세미콜론을 사용합니다'등과 같은 제목을 가진 수십 개의 기사가 있습니다.

그러나 파이썬에서는 아무도 세미콜론을 사용하지 않으며 정확히 같은 문제가 있습니다.

def test():
    # This will return 'undefined', because return is a valid statement
    # and  "john" is a valid statement on its own.
    return 
    "john"

정확히 동일하게 작동하지만 아무도 파이썬의 행동을 치명적으로 두려워하지 않습니다.

나는 자바 스크립트가 잘못 행동하는 경우가 거의 없어서 쉽게 피할 수 있다고 생각합니다. 줄 바꿈 + 값? 사람들이 정말로 그렇게 많이합니까?

의견이 있습니까? 자바 스크립트에서 세미콜론을 사용합니까? 그 이유는 무엇입니까?


3
정확히 동일하게 작동하지 않습니다. 세미콜론 삽입은 줄 바꿈이 JavaScript의 어느 위치에 있더라도 반드시 진행되지는 않습니다. 이 Wikipedia 페이지 의 두 번째 예를 참조하십시오 . 이 예에서 줄 바꿈이있는 위치에는 세미콜론이 삽입되지 않습니다.
Reid

1
내 요점은 세미콜론을 사용하고 정확하게 사용하지 않았다는 것이 아니라 요점은 자바 스크립트와 파이썬의 가장 중요한 경우가 동일하다는 것입니다. 무슨 일이 일어나고 있는지 알아야하는 몇 가지 중요한 경우가 있습니다. 내가 주제에 대해 읽은 최고의 기사 : inimino.org/~inimino/blog/javascript_semicolons
Einar Egilsson

4
문장에 마침표를 사용하는 것과 같은 이유로 세미콜론을 JavaScript에 넣습니다. 통역사는 일반적으로 성명서가 아닌 성명서가 아닌 성명서를 이해할 수 있습니다.
JD Isaacks

3
예제에서 유효한 파이썬 작성을 고려할 수 있습니다. 코멘트 인디케이터는 #`// '가 아닙니다.
Aaron Dufour

2
"명시 적은 항상 암시 적보다 낫다"

답변:


62

그 이유는 파이썬에서 줄 바꿈은 코드 줄을 구분하는 명확한 방법이기 때문입니다. 이것은 의도적으로 설계된 작업이며이 작업 방식을 철저히 고려했습니다. 결과적으로 파이썬 코드는 특별한 줄 끝 마커 (줄 바꿈 제외)없이 완벽하게 읽을 수 있고 모호하지 않습니다.

반면에 자바 스크립트는 문장이 항상 세미콜론으로 끝나는 C와 유사한 구문을 염두에두고 설계되었습니다. 언어에 오류에 대한 내성을 더 높이기 위해 코드를 올바르게 만들기 위해 추가 세미콜론이 어디로 가야하는지 추측합니다. 이것은 C와 같은 구문에 맞게 수정 되었기 때문에 항상 예상대로 작동하지는 않으며 (때때로 스크립트 인터프리터가 잘못 추측 함) 상당히 반 직관적 인 코드를 만들 수 있습니다. \

또는 "명시적인 것이 묵시적인 것보다 낫다"라는 말로 논쟁 : 파이썬에서 줄 바꿈은 이미 완전히 명시 적이지만 자바 스크립트에서는 모호하므로 세미콜론을 추가하여 명시 적으로 만듭니다.


3
아, 그리고 인용 부호를 사용하여 주석에 코드를 넣을 수 있습니다.
tdammers

1
자동 세미콜론 삽입이 예기치 않은 일을하는 경우의 좋은 예는 다음과 같습니다. pastebin.com/aVeWGdya
HoLyVieR

5
파이썬에서 규칙은 매우 간단합니다. 닫히지 않은 여러 줄 문자열 ( "" ", '' '), 닫히지 않은 dict ({}), 닫히지 않은 목록 ([]) 또는 백 슬래시가 없으면 명령문은 줄 바꿈으로 끝납니다. 자바 스크립트에서 규칙은 훨씬 더 복잡합니다
Aaron Dufour

5
99 %의 오류를 다루는 것은 찾기 어려운 오류 만 남기는 좋은 방법입니다. 100 % 문제를 다루는 쉬운 규칙이 있기 때문에 파이썬으로 남겨 두는 것이 좋습니다.
Aaron Dufour

1
@Aaron : "닫히지 않은 괄호 (())"를 잊었습니다. (괄호는 튜플에만 사용되는 것이 아니기 때문에 "닫히지 않은 튜플"은 아닙니다.)
JAB

28

파이썬에서 작동하는 방식과는 근본적으로 다른 점이 있다고 생각합니다. Einar Egilsson 포스트에서 인용 한 내용 : "다음 줄의 첫 번째 토큰을 같은 문장의 일부로 파싱 할 수 있다면 세미콜론은 줄 끝에 암시되지 않습니다".

파이썬에서 줄 바꿈은 괄호 안에있는 식과 같이 상당히 명백한 경우를 제외하고는 항상 문을 끝냅니다. 반면에 JavaScript는 명령문을 종료하기 전에 가능한 한 많은 행을 구문 분석하여 다음과 같은 결과를 가져올 수 있습니다.

// Define a function and name it area.
area = function(r) {
    return r * r * 3.14159
}

// Fooled you! We're actually invoking it.
(14)

8
이제 여기에 재미있는 비틀기가 있습니다. 14를 (a + 1) ? do_something() : do_something_else();갑자기 같은 것으로 바꾸십시오. 면적이 반환 값으로 설정되어 do_something()있거나 do_something_else()혼란스러워합니다.
Reid

20

프로덕션 모드에서 종종 JS 파일을 최소화합니다. 주석과 줄 바꿈을 제거하는 수단.

세미콜론을 사용하지 않으면 Javascript가 손상됩니다.


8
알겠습니다. 유효합니다. 그러나 최소화 기가 실제 파서 인 경우 필요에 따라 다시 삽입 할 수 있습니다. 또는 줄 바꿈을 제거하지 마십시오. => 줄 바꿈을 유지하고 세미콜론을 잃어 버립니다. 대략 같은 숫자이므로 잃어버린 것이 없습니다.
Einar Egilsson

2
@Einar Egilsson Closure Compiler는 실제로 이것을 수행합니다.
seriousdev

1
모든 것이 동일하면 개행은 세미콜론과 동일한 바이트 수입니다. 최소화 기가 모든 새 줄을 제거 할 수 있지만 세미콜론이 있어야합니다. 그것은 심지어 교환이다.
로건 베일리

3
@Logan : 물론 1 바이트 줄 바꿈을 가정하고 있습니다. ;-)
Cameron

1
물론, 자바 스크립트 대신 파이썬을 사용했다면 동일한 방법으로 코드를 적게 작성해야하므로 세미콜론 은 들여 쓰기보다 몇 바이트 적은 바이트를 사용한다는 사실이 문제가됩니다.
BlueRaja-대니 Pflughoeft

5

설명한대로 작동하지 않습니다.

Javascript에는 자동 세미콜론 삽입이라는 기능이 있습니다. 기본적으로 파서에 잘못된 토큰이 있고 그 이전의 마지막 토큰이 줄 바꿈 인 경우 파서는 줄 바꿈이있는 곳에 세미콜론을 삽입합니다.

이것은 잘못이다. 예:

return
  1 + 2;

1는 완벽하게 유효한 토큰이지만 파서는 여전히 바로 뒤에 세미콜론을 삽입합니다 return.

보시다시피 세미콜론이 어디서 발생하는지 정확하게 알 수 없습니다.

자동 삽입 문제는 두 가지입니다.

  • 예를 들어, 사람들은 자동 삽입으로 삽입해야한다고 결정할 수없는 세미콜론을 남길 수 있습니다.
  • 또한 세미콜론은 위와 같이 의도하지 않은 곳에 삽입 될 수 있습니다.

물론 모든 문장 다음에 세미콜론을 사용하면 첫 번째 오류 원인에만 도움이됩니다.

어쨌든 지금까지 짐작할 수 있듯이 C와 같은 구문에서 자동 세미콜론 삽입은 나쁜 생각이라고 생각합니다.


1
ECMA 스크립트 사양은 세미콜론이 삽입 될 사례를 명시 적으로 지정하므로 "세미콜론이 발생할 정확한 위치를 알 수 없습니다"라는 줄이 잘못되었습니다. 문제는 경우에 따라 직관적이지 않으므로 작동 방식을 이해하지 못하는 사람을 가르치기가 더 어렵다는 것입니다.
zzzzBov

1
@ zzzzBov : 예, 정확한 사양이 있지만 코딩하는 동안 실제로 모든 경우를 염두에두고 있습니까? 확실합니까? 프로그래머는 게으 르며 당연히 그렇습니다. 그들은 훨씬 더 간단한 규칙이있을 때 복잡한 규칙을 기억하고 싶지 않습니다. 그래서 그들은 그것을 기억해야 할 것입니다.
Svante

세미콜론 삽입이 크게 필요하지 않다는 데 동의합니다. "반 콜론이 어디로 가고 있는지 전혀 모른다"와 "세미콜론 삽입에 대한 스펙이 직관적이지 않다"는 것 사이에는 차이가 있습니다.
zzzzBov

1
@Svante : 그러나 리턴 예제는 어쨌든 이러한 규칙을 알아야한다는 것을 보여줍니다. 세미콜론을 사용했지만 원하는 것을 수행하는 데 도움이되지 않았습니다. 따라서 언어에이 기능이 있다고 가정하면 (1) 모든 곳에서 세미콜론을 작성하고 규칙을 알 수 있으므로 어떤 상황이 발생하는지 이해합니다. (2) 모든 곳에서 세미콜론을 작성하지 않고 규칙을 이해하여 어떤 일이 발생하는지 이해합니다. 그 선택이 주어지면 나는 세미콜론을 건너 뛰고 싶다고 생각합니다
Einar

4

한 가지 간단한 이유를 말씀 드리겠습니다.

자바 스크립트는 "kinda java-ish"또는 "kinda C-ish"로 보입니다. 물론 그것은 역동적 인 언어이므로 다르게 보입니다 ...하지만 직면하십시오- 중괄호가 있습니다. 중괄호가있는 언어에는 일반적으로 세미콜론이 있습니다. 자연스러운 반사 작용이 시작되어 손가락을 세 번 콜론으로 향하게합니다 Enter.

반대로 파이썬은 한 눈에 완전히 다르게 보입니다. 따라서 "표준 보링 언어"와 거의 유사하지 않거나 직관적으로 형성되지 않으며 "파이썬 모드"로 들어갈 때 세미콜론이 부족합니다.


2

가 있습니다 좋은 이유가 되지 자바 스크립트에서 사용 세미콜론 삽입하려면.

주로 ECMAScript 표준에 정의 된 세미콜론 삽입이 직관적이지 않기 때문입니다. @Svante return는 줄 바꿈 사용으로 인해 문제가 발생 하는 경우를 지적합니다.

그가 언급하지 않은 것은 세미콜론 삽입도 원하는지 여부에 관계없이 세미콜론을 사용 하면 문제가 발생할 수 있다는 것입니다.

세미콜론 삽입을 사용 하지 않는 또 다른 매우 좋은 이유 는 출력 제어입니다. 대부분의 경우 JavaScript는 프로덕션에 사용되기 전에 축소기를 통해 실행됩니다. 일부 축소 기는 자동 세미콜론 삽입 사례를 처리 할 수 ​​있지만 완벽하게 작동하는 데 의존 할 이유가 없습니다.

또한 콘텐츠 관리 시스템의 경우 인라인 JavaScript가 자동 축소 될 수 있으며 자동 축소 기가 단순히 주석을 제거하고 각 줄의 시작과 끝에서 공백 (줄 바꿈 포함)을 자르는 많은 경우를 보았습니다.

어떤 도구를 선택할지 선택하지 않은 저자에게는 대부분의 경우에 적합한 형식을 고수하는 것이 훨씬 쉽습니다.


아, 죄송하지만 세 번째 단락에 대한, 내가 언급을 나의 마지막에서 두 번째 문장이다. :)
Svante

예, 툴링 문제는 유효합니다 (예 : 클로저 컴파일러와 같이 좋은 축소 기가이를 처리해야하지만). 그러나 제 생각에는 '반환'예와 같은 것을 피하기 위해 어쨌든이 규칙을 알아야합니다. 규칙을 알고 나면 특히 코드 (IMO)를 더 읽기 쉽게하기 때문에이 기능을 사용할 수도 있습니다.
Einar Egilsson

1

파일 JavaScript 파일을 축소 할 때 세미콜론을 사용하지 않으면 실패 할 수 있습니다. 그래서 제가 무서워합니다.


1

Javascript에서는 자동 세미콜론 삽입없이 구문 적으로 올바른 프로그램을 작성할 수 있으며 ASI는 해당 프로그램을 다른 구문 적으로 올바른 프로그램으로 변환합니다 (예 : 값을 리턴하는 코드를 아무것도 리턴하지 않는 코드로 변환). 파이썬에는 비슷한 경우가 없습니다. 파이썬 에서 명령문 종료 할 수 있는 줄 바꿈 은 백 슬래시로 이스케이프되지 않는 한 명령문 종료합니다. 기술적으로 Javascript의 규칙이 똑같이 결정 론적이라고 생각하지만 문장을 끝내는 Javascript의 규칙을 한 문장으로 요약 할 수 있는지 모르겠습니다.


1

대부분의 경우 JavaScript의 ASI는 예상대로 처리합니다. ASI의 한 가지 예는 아마도 당신이 기대하는 방식으로 행동하지 않을 것입니다 :

var i = 0

(function() {
   // do something
})()

이것은 0익명 함수로 함수 를 호출 한 다음 결과를 실행하는 것으로 해석됩니다 . 이 경우 할당을 수행 한 다음 즉시 익명 함수를 실행하려고합니다.

ASI에 익숙하지 않은 사람에게는 이와 같은 문제가 발생할 때 매우 혼란 스러울 수 있으므로 항상 팀의 개발자가 세미콜론을 사용하는 것이 좋습니다.

(제쳐두고 : 개인 / 사이드 프로젝트를 수행 할 때 세미콜론을 사용하지 않습니다. 다른 사람이 코드를 유지할 필요가 없기 때문입니다.)


1

당신처럼, 나는 그것이 편집증이라고 생각합니다. 세미콜론 삽입 규칙은 Python 및 CoffeeScript와 마찬가지로 JavaScript에서도 잘 정의됩니다. 아무도 세미콜론으로 파이썬이나 CoffeeScript를 버리지 않습니다. 왜 JavaScript가 다르게 취급됩니까?

나는 이것이 약 10 년 전부터 전형적인 자바 스크립트 코드의 비참한 상태에 대한 과잉 반응이라고 생각한다. 당황 스러웠습니다. JavaScript로 좋은 코드를 작성할 수 없습니다!

그런 다음 사람들이 와서 JavaScript로 아름답고 명확한 코드를 작성할 있음을 증명하려고 노력했습니다 . " 항상 세미콜론 사용"규칙이이 물결의 일부였습니다. 솔직히 말하면 몇 가지 상황을 좀 더 명확하게 만들 수 있습니다.

JavaScript가 여전히 다르게 취급되는 이유는 무엇입니까?

관성이 있습니다. 명시 적으로 구조화 된 코드를 좋아 하는 사람들은 종종 C 스타일 언어를 선호 한다는 것을 간과해서는 안됩니다 . 암시 적으로 구조화 된 코드를 좋아하는 사람들은 종종 CoffeeScript와 같은 비 C 언어 언어로 넘어갑니다.


0

일관성을 유지하기 위해 Javascript로 엄격하게 사용합니다. 대부분의 줄에

파이썬은 한 줄에 여러 문장과 같은 엣지 케이스를 가지고 있으며, 자바 스크립트에는 그것들이 있으며 정기적으로 사용되는 것을 알기 때문에 나는 그들이 사용되는 규범을 준수합니다.

같은 줄에서 여러 문장을 사용할 수 없으므로 세미콜론을 사용하지 않습니다.


예, 파이썬 예제를 수정했습니다. 그러나 요점은 여전히 ​​파이썬에는 세미콜론이 있으므로 모든 문장 뒤에 넣을 수 있습니다 (각 줄에 둘 이상이있는 경우)하지만 사람들은 사용하지 않습니다.
Einar Egilsson

0

bundle-fu와 같은 것을 사용하고 웹 응용 프로그램에 대한 자산 관리자를 레일에서 사용하는 경우 Javascript의 토큰 끝에 세미콜론이 없으면 끔찍하게 중단됩니다. 하나를 넣는 것이 좋습니다.


큰 세 가지 인 YUI Compressor, Closure Compiler 및 UglifyJS는 모두 세미콜론 삽입을 수행합니다. JSMin의 루비 포트에 문제가 있다는 것은 놀라운 일이 아닙니다.
Benjamin Atkin

0

IE의 정확한 버전을 기억할 수는 없지만 세미콜론이 없으면 IE에서 문자 그대로 오류가 발생하는 경우가 있습니다. IIRC는 다음과 같은 글로벌 범위에있을 때입니다.

var myFunc = function() {
  ...
}

추가하지 않으면; 닫는 중괄호 후에 프로그램은 실제로 일부 버전의 IE에서 실패합니다. 다른 이유와 함께 (Crockford가 항상 명시 적으로 사용하도록 권장하는 것을 포함하여) 모든 경우에 항상 명시 적으로 사용하도록 이끌었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.