저는 코드 블록을 사용하여 정적 함수 변수를 C로 시뮬레이션하고 있습니다. 기본 설정은 다음과 같습니다.
{
let bob = 5;
function b() {
console.log(bob++);
}
}
이제 크롬에서는 불만없이 잘 컴파일됩니다. 그러나 Safari에서는
SyntaxError : 예기치 않은 식별자 'bob'. 속성 이름 'let'뒤에 ':'가 있어야합니다.
Chrome과 Safari 모두 ECMAScript 6을 처리하기 때문에 이 불일치를 일으키는 원인을 모릅니다.
문제는 코드가 느슨한 모드이고 블록에서 함수를 선언하고 있다는 것입니다. 블록의 함수 선언은 ES2015에서만 표준화되었으며 엄격( Use strict ) 모드에서는 의미가 있지만 느슨한 모드에서는... 이상합니다.
엄격 모드( Use strict ) 에서 코드는 다음과 같이 작동합니다. 당신은 기대하거나 그렇지 않을 수 있습니다. bob
은 b
에 액세스 할 수 있으며, 다른 작업을 수행하지 않는 한 해당 블록 외부에서 bob
또는 b
에 액세스 할 수 없습니다. 외부에 노출시킵니다.
다음은 Safari와 iOS Safari 모두에서 테스트하는 데 사용할 수있는 예입니다 (후자 만 사용할 수 있습니다). 이 버전은 오류를 제공합니다.
<script>
window.onerror = e => {
document.body.insertAdjacentText("beforeend", String(e));
};
</script>
<script>
{
let bob = 5;
function b() {
document.body.insertAdjacentText("beforeend", bob++);
}
b();
}
</script>
오류는 다음과 같습니다.
ReferenceError : 변수를 찾을 수 없음 : bob
이 버전은 다음과 같이 작동합니다.
<script>
window.onerror = e => {
document.body.insertAdjacentText("beforeend", String(e));
};
</script>
<script>
"use strict"; // <============================
{
let bob = 5;
function b() {
document.body.insertAdjacentText("beforeend", bob++);
}
b();
}
</script>
또한 최신 버전의 JavaScriptCore (Apple의 JavaScript 엔진) 인 v265499에서 동작을 복제했습니다. 내가 ¹ 설치하고 로컬에서 실행하고 (console.log
/ insertAdjacentText
를 대부분의 원시 엔진 실행 파일에서 사용할 수있는 print
로 변경) strict 모드가 아닌 느슨한 모드에서 동일한 오류가 발생합니다.
블록 외부에서 b
를 사용할 수있게하려면 다음과 같이하는 것이 좋습니다.
"use strict";
const b = (() => {
let bob = 5;
return function b() {
console.log(bob++);
};
})();
b();
많이 부피가 크지만 ... 또는 let
을 사용하면 다음과 같습니다.
"use strict";
let b;
{
let bob = 5;
b = function b() {
print(bob++);
};
}
b();
¹ 매우 편리한 jsvu
유틸리티 를 사용합니다.
오류 메시지에 따라 Safari는 블록을 객체 리터럴로 해석합니다. 구문은 유효하지만 Safari가 질식하는 것 같습니다.
내 콘솔에서 이것을 시도했을 때 블록 바로 뒤에 명령문을 배치하여 작동시킬 수있었습니다.
{ let bob = 5; function b(){ console.log(bob++); } } console.log('foo');
그러나 이것은 클로저를 생성하지 않고 블록 범위 밖으로 함수를 끌어 올리는 것처럼 보이며, 변수 bob
을 찾을 수 없다고 주장하는 ReferenceError
가 발생합니다.
함수에 명시 적으로 래핑하고 엄격 모드( Use strict ) 는 동작을 변경할 수 있습니다.
function strict() {
'use strict';
{
let bob = 5;
function b() {
console.log(bob++);
}
return b;
}
}
strict()();
그리고 작동했습니다!
TL : DR; 느슨한 모드에서 블록 처리가 이상합니다. 블록 내에서 함수를 정의 할 때 Use strict 모드를 사용하십시오.