[javascript] ECMAScript 2015 : for 루프의 const

완전한 ECMAScript 2015 구현에서 작동해야하는 두 가지 (또는 둘 다) 코드 조각 중 어느 것입니까?

for (const e of a)

for (const i = 0; i < a.length; i += 1)

내 이해에서 첫 번째 예제는 e각 반복마다 초기화 되기 때문에 작동 합니다. 이것은 i두 번째 버전 의 경우에도 해당되지 않습니까?

기존 구현 (Babel, IE, Firefox, Chrome, ESLint)이 일관 적이 지 const않고 두 루프 변형의 다양한 동작과 함께 완전한 구현을 가지고 있기 때문에 혼란 스럽습니다 . 나는 또한 표준에서 구체적인 요점을 찾을 수 없으므로 많이 감사하겠습니다.



답변

다음 for-of 루프가 작동합니다.

for (const e of a)

ES6 사양은이를 다음과 같이 설명합니다.

ForDeclaration : LetOrConst ForBinding

http://www.ecma-international.org/ecma-262/6.0/index.html#sec-for-in-and-for-of-statements-static-semantics-boundnames

명령형 for 루프는 작동하지 않습니다.

for (const i = 0; i < a.length; i += 1)

이는 루프 본문이 실행되기 전에 선언이 한 번만 평가되기 때문입니다.

http://www.ecma-international.org/ecma-262/6.0/index.html#sec-for-statement-runtime-semantics-labelledevaluation


답변

이번에는 사양을 인용하지 않겠습니다. 예를 들어 어떤 일이 발생하는지 이해하는 것이 더 쉽기 때문입니다.

for (const e of a) …

기본적으로 다음과 같습니다.

{
    const __it = a[Symbol.iterator]();
    let __res;
    while ((__res = __it.next()) && !__res.done) {
        const e = __res.value;
        …
    }
}

단순화를 위해 표현식에 e대한 TDZ가 있고 루프가 조기에 종료되는 경우 ( 또는 본문에서) a다양한 __it.return()/ __it.throw(e)호출 이 있다는 것을 무시했습니다 .breakthrow

for (const i = 0; i < a.length; i += 1) …

기본적으로

{
    const i = 0;
    while (i < a.length) {
        …
        i += 1;
    }
}

대조적으로let 하는 constA의 선언 for루프는 각 루프 반복에서 다시 선언되지 않는다 (어쨌든 재실행 – 더 initialiser는 아니다). break첫 번째 반복이 아니라면 i +=여기에 던질 것입니다.


답변

두 번째 예제는 i각 반복이 아니라 한 번 선언 되기 때문에 확실히 작동하지 않아야합니다. 이것은 해당 범주의 루프가 작동하는 방식의 함수일뿐입니다.

일반 브라우저에서 시도해 볼 수 있습니다.

for (var i = 0, otherVar = ""; i < [1,2,3,4].length; i += 1){
  console.log(otherVar)
  otherVar = "If otherVar was initialized on each iteration, then you would never read me.";
}

루프 const에서 완전히 허용되지 않는 경우는 아닙니다 for. 그것만 for이 const를 수정할 것입니다.

다음은 유효합니다.

for(const i = 0;;){ break }
for(const i = 0; i < 10;){ break; }

다음은 유효하지 않습니다.

for(const i = 0;;){ ++i; break; }
for(const i = 0;;++i){ if(i > 0) break; }

ES2015 사양을 읽은 후 Firefox가 SyntaxError를 제공하는 이유를 잘 모르겠습니다 (Mozilla의 영리한 사람들이 정확하다고 확신하지만) 예외를 발생시켜야하는 것 같습니다.

환경 레코드에서 새롭지 만 초기화되지 않은 변경 불가능한 바인딩을 만듭니다. 문자열 값 N은 바인딩 된 이름의 텍스트입니다. S가 true이면 바인딩이 초기화되기 전에 바인딩 값에 액세스하려고 시도하거나 초기화 된 후에 설정하면 해당 바인딩을 참조하는 작업의 엄격 모드 설정에 관계없이 항상 예외가 발생합니다. S는 기본값이 false 인 선택적 매개 변수입니다.


답변