[javascript] JavaScript의 자동 세미콜론 삽입 (ASI) 규칙은 무엇입니까?
글쎄, 먼저 브라우저 의존적인지 물어봐야합니다.
유효하지 않은 토큰이 발견되면 유효하지 않은 토큰까지 코드 섹션이 유효하며 세미콜론은 토큰 앞에 줄 바꿈이 있으면 토큰 앞에 삽입됩니다.
그러나 세미콜론 삽입으로 인한 버그에 대한 일반적인 예는 다음과 같습니다.
return
_a+b;
.a는 유효한 토큰이므로이 규칙을 따르지 않는 것 같습니다.
반면에 콜 체인을 끊으면 예상대로 작동합니다.
$('#myButton')
.click(function(){alert("Hello!")});
누구든지 규칙에 대해 더 깊이 설명하고 있습니까?
답변
우선 자동 세미콜론 삽입 (간결성을 위해 ASI라고도 함)의 영향을받는 명령문을 알아야합니다.
- 빈 진술
var
성명서- 표현 문
do-while
성명서continue
성명서break
성명서return
성명서throw
성명서
ASI의 구체적인 규칙은 사양 §11.9.1 자동 세미콜론 삽입 규칙에 설명되어 있습니다.
세 가지 경우가 설명됩니다.
-
문법에서 허용하지 않는 토큰 (
LineTerminator
또는}
)이 발견되면 다음과 같은 경우 세미콜론이 앞에 삽입됩니다.- 토큰은 이전 토큰과 하나 이상 구분됩니다
LineTerminator
. - 토큰은
}
예 :
{ 1 2 } 3
로 변환
{ 1 ;2 ;} 3;
은
NumericLiteral
1
첫 번째 조건, 광고 토큰 인 터미네이터 다음을 만족한다.
는2
두 번째 조건 인 다음 토큰을 충족}
. - 토큰은 이전 토큰과 하나 이상 구분됩니다
-
토큰의 입력 스트림의 끝이 발생하고 구문 분석기가 입력 토큰 스트림을 하나의 완전한 프로그램으로 구문 분석 할 수없는 경우 입력 스트림의 끝에 세미콜론이 자동으로 삽입됩니다.
예 :
a = b ++c
다음으로 변환됩니다.
a = b; ++c;
-
이 경우는 문법의 일부 생산에서 토큰을 허용하지만 생산이 제한된 생산 인 경우에 발생합니다. 인 경우 세미콜론이 제한된 토큰 앞에 자동으로 삽입됩니다.
제한된 제작 :
UpdateExpression : LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ContinueStatement : continue ; continue [no LineTerminator here] LabelIdentifier ; BreakStatement : break ; break [no LineTerminator here] LabelIdentifier ; ReturnStatement : return ; return [no LineTerminator here] Expression ; ThrowStatement : throw [no LineTerminator here] Expression ; ArrowFunction : ArrowParameters [no LineTerminator here] => ConciseBody YieldExpression : yield [no LineTerminator here] * AssignmentExpression yield [no LineTerminator here] AssignmentExpression
고전적인 예
ReturnStatement
:return "something";
로 변환
return; "something";
답변
로부터 직선 ECMA-262, 제 5 판 인 ECMAScript 사양 :
7.9.1 자동 세미콜론 삽입 규칙
세미콜론 삽입에는 세 가지 기본 규칙이 있습니다.
- 프로그램이 왼쪽에서 오른쪽으로 구문 분석 될 때 토큰 ( 불쾌한 토큰 이라고 함) 문법 생성에서 허용되지 않는 )이 발생하면 다음 중 하나 이상에 해당하는 경우 위반 토큰 앞에 세미콜론이 자동으로 삽입됩니다. 조건은 사실이다 :
- 문제가되는 토큰은 하나 이상의 토큰으로 이전 토큰과 분리됩니다.
LineTerminator
.- 문제의 토큰은 }입니다.
- 프로그램이 왼쪽에서 오른쪽으로 구문 분석 될 때 토큰 입력 스트림의 끝에 도달하고 구문 분석기가 입력 토큰 스트림을 하나의 완전한 ECMAScript로 구문 분석 할 수없는 경우
Program
끝에 도달하고 경우 세미콜론이 자동으로 끝에 삽입됩니다. 입력 스트림.- 프로그램이 왼쪽에서 오른쪽으로 구문 분석 될 때 문법의 일부 생산에서 허용되는 토큰이 발견되지만 생산은 제한된 생산 이며 토큰은 주석 바로 다음에 터미널 또는 비 터미널의 첫 번째 토큰이됩니다. 제한된 프로덕션 내에서 ” [
LineTerminator
여기 없음 ] “(이러한 토큰을 제한된 토큰이라고 함) 제한된 토큰은 하나 이상의 LineTerminator에 의해 이전 토큰과 분리 된 다음 세미콜론이 제한된 토큰 앞에 자동으로 삽입됩니다.그러나 이전 규칙에는 추가 재정의 조건이 있습니다. 세미콜론이 빈 명령문으로 구문 분석되거나 해당 세미콜론이 for명령문 헤더의 두 세미콜론 중 하나가되면 세미콜론이 자동으로 삽입되지 않습니다 (12.6 참조). .삼).
답변
스펙의 세 가지 규칙을 너무 잘 이해할 수 없었습니다.보다 명확한 영어를 원합니다. 그러나 여기 JavaScript에서 수집 한 내용이 있습니다 : The Definitive Guide, 6th Edition, David Flanagan, O’Reilly, 2011 :
인용문:
JavaScript는 모든 줄 바꿈을 세미콜론으로 취급하지는 않습니다. 일반적으로 세미콜론없이 코드를 구문 분석 할 수없는 경우에만 줄 바꿈을 세미콜론으로 처리합니다.
다른 인용문 : 코드
var a
a
=
3 console.log(a)
JavaScript는 두 번째 줄 바꿈을 세미콜론으로 취급하지 않습니다. 더 긴 명령문 a = 3을 계속 구문 분석 할 수 있기 때문입니다.
과:
JavaScript가 줄 바꿈을 두 번째 줄을 첫 번째 줄의 명령문 연속으로 구문 분석 할 수없는 경우 세미콜론으로 해석한다는 일반적인 규칙에 대한 두 가지 예외. 첫 번째 예외는 return, break 및 continue 문을 포함합니다.
…이 단어 뒤에 줄 바꿈이 나타나면 … JavaScript는 항상 해당 줄 바꿈을 세미콜론으로 해석합니다.
… 두 번째 예외는 ++ 및 −− 연산자와 관련이 있습니다 …이 연산자 중 하나를 접미사 연산자로 사용하려면 해당 연산자가 적용되는 식과 같은 줄에 나타나야합니다. 그렇지 않으면 줄 바꿈은 세미콜론으로 처리되고 ++ 또는-는 다음 코드에 적용되는 접두사 연산자로 구문 분석됩니다. 예를 들어 다음 코드를 고려하십시오.
x
++
y
로 해석
x; ++y;
되지 않습니다.x++; y
그래서 나는 그것을 단순화하려고 생각합니다.
(1) 일부 키워드가 좋아 후 : 2가지 경우를 제외하고 – 일반적으로, 자바 스크립트는 오랫동안 말이뿐만 코드의 연장으로 취급한다 return
, break
, continue
, 그리고 그것을 보는 경우 (2) ++
또는 --
새 줄에 다음을 추가합니다 ;
이전 줄의 끝에서.
“이해가되는 한 코드의 연속으로 처리”에 대한 부분은 정규 표현식의 욕심 매칭과 같은 느낌을줍니다.
위에서 말했듯이, 그 의미는 return
줄 바꿈 하는 JavaScript 인터프리터는;
(다시 인용 : 다음과 같은 단어 뒤에 줄 바꿈이 나타나는 경우 return
] JavaScript는 항상 줄 바꿈을 세미콜론으로 해석합니다)
이 때문에 고전적인 예는
return
{
foo: 1
}
JavaScript 인터프리터는 다음과 같이 처리하므로 예상대로 작동하지 않습니다.
return; // returning nothing
{
foo: 1
}
다음 직후에 줄 바꿈이 없어야합니다 return
.
return {
foo: 1
}
제대로 작동합니다. after 문 ;
을 사용하는 규칙을 따르는 경우 자신을 삽입 할 수 있습니다 ;
.
return {
foo: 1
};
답변
세미콜론 삽입 및 var 문에 대해서는 var를 사용할 때 쉼표를 잊어 버리지 만 여러 줄에 걸쳐 있어야합니다. 누군가 어제 내 코드에서 이것을 발견했습니다.
var srcRecords = src.records
srcIds = [];
그것은 실행되었지만 그 효과는 srcIds 선언 / 할당이 전역 적이었습니다. 이전 줄에 var가있는 로컬 선언이 더 이상 적용되지 않았기 때문에 자동 세미콜론 삽입으로 인해 해당 명령문이 완료된 것으로 간주되었습니다.
답변
내가 찾은 JavaScript의 자동 세미콜론 삽입에 대한 가장 문맥 설명 은 Crafting Interpreters 에 관한 책에서 비롯된 것 입니다.
JavaScript의 “자동 세미콜론 삽입”규칙이 이상합니다. 다른 언어에서는 대부분의 줄 바꿈이 의미가 있다고 생각하고 여러 줄 문장에서 몇 개만 무시해야하는 경우 JS는 그 반대라고 가정합니다. 구문 분석 오류가 발생하지 않는 한 모든 줄 바꿈을 의미없는 공백으로 처리합니다. 그렇다면 문법적으로 유효한 것을 얻기 위해 이전 줄 바꿈을 세미콜론으로 바꾸려고합니다.
그는 당신이 냄새를 맡을 때 그것을 계속 설명합니다 .
이 디자인 노트는 그것이 어떻게 작동하는지, 나쁜 아이디어 인 다양한 방법보다 훨씬 적은 방법에 대해 자세히 설명하면 디자인 디아 트라이브로 바뀔 것입니다. 엉망입니다. JavaScript는 이론적으로 언어를 허용하더라도 많은 스타일 가이드가 모든 문장 다음에 명시 적 세미콜론을 요구하는 유일한 언어입니다.
답변
추가하기 만하면
const foo = function(){ return "foo" } //this doesn't add a semicolon here.
(function (){
console.log("aa");
})()
즉시 호출 된 함수 표현식 (IIFE)을 사용하여 이것을보십시오