완전한 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
명령형 for 루프는 작동하지 않습니다.
for (const i = 0; i < a.length; i += 1)
이는 루프 본문이 실행되기 전에 선언이 한 번만 평가되기 때문입니다.
답변
이번에는 사양을 인용하지 않겠습니다. 예를 들어 어떤 일이 발생하는지 이해하는 것이 더 쉽기 때문입니다.
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)
호출 이 있다는 것을 무시했습니다 .break
throw
for (const i = 0; i < a.length; i += 1) …
기본적으로
{
const i = 0;
while (i < a.length) {
…
i += 1;
}
}
대조적으로let
하는 const
A의 선언 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 인 선택적 매개 변수입니다.