ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JavaScript 코드 블록에서 가끔 발생하는 오류
    카테고리 없음 2020. 8. 12. 15:39

    질문

    저는 코드 블록을 사용하여 정적 함수 변수를 C로 시뮬레이션하고 있습니다. 기본 설정은 다음과 같습니다.

    {
        let bob = 5;
        function b() {
            console.log(bob++);
        }
    }

    이제 크롬에서는 불만없이 잘 컴파일됩니다. 그러나 Safari에서는

    SyntaxError : 예기치 않은 식별자 'bob'. 속성 이름 'let'뒤에 ':'가 있어야합니다.

    Chrome과 Safari 모두 ECMAScript 6을 처리하기 때문에 이 불일치를 일으키는 원인을 모릅니다.

     

    답변1

    문제는 코드가 느슨한 모드이고 블록에서 함수를 선언하고 있다는 것입니다. 블록의 함수 선언은 ES2015에서만 표준화되었으며 엄격( Use strict ) 모드에서는 의미가 있지만 느슨한 모드에서는... 이상합니다.

    엄격 모드( Use strict ) 에서 코드는 다음과 같이 작동합니다. 당신은 기대하거나 그렇지 않을 수 있습니다. bobb에 액세스 할 수 있으며, 다른 작업을 수행하지 않는 한 해당 블록 외부에서 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유틸리티 를 사용합니다.



    답변2

    오류 메시지에 따라 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 모드를 사용하십시오.



     

     

     

     

    출처 : https://stackoverflow.com/questions/63362693/error-sometimes-thrown-with-javascript-code-block

    댓글

Designed by Tistory.