ES6의 블록 수준 역할 영역 및 함수 선언 - 독서 노트

함수는 블록급 역할 영역에서 설명할 수 있습니까?


ES5에서는 함수는 최상위 역할 및 함수 역할 도메인에서만 선언할 수 있으며 블록 수준 역할 도메인에서는 선언할 수 없습니다.

//    
if (true) {
  function f() {}
}
//    
try {
  function f() {}
} catch(e) {
  // ...
}

위의 두 함수는 ES5의 규정에 따라 모두 불법이라고 성명하였다.

그러나 브라우저가 이 규정을 준수하지 않았기 때문에 이전의 낡은 코드를 호환하기 위해 블록급 역할 영역에서 함수를 성명하는 것을 지원하기 때문에 상기 두 가지 상황은 실제적으로 모두 실행되고 오류가 발생하지 않는다.


ES6를 살펴보겠습니다.


ES6는 블록 레벨 역할 영역을 도입하여 블록 레벨 역할 영역에서 함수를 명시적으로 선언할 수 있도록 합니다.ES6는 블록 레벨 역할 영역에서 함수 선언문은 let과 유사하며 블록 레벨 역할 영역 외부에서는 참조할 수 없다고 규정한다.


코드는 다음과 같습니다.

function f() { console.log('I am outside!'); }
(function () {
  if (false) {
    //         f
    function f() { console.log('I am inside!'); }
  }
  f();
}());

ES6는 이론적으로 "I am outside!"를 얻게 된다.블록급 작용역에서 설명하는 함수는let과 유사하기 때문에 작용역 이외에 영향을 주지 않습니다.그런데 만약 당신이 정말로 ES6 브라우저에서 위의 코드를 실행한다면, 오류가 발생할 것이다. 이것은 왜 그런가?


블록급 작용역에서 성명된 함수의 처리 규칙을 바꾸면 오래된 코드에 큰 영향을 미칠 수 있기 때문이다.이로 인해 발생하는 비호환성을 경감시키기 위해 ES6는 브라우저의 실현이 위의 규정을 준수하지 않고 자신의 행위 방식을 허용할 수 있도록 규정하고 있다.


4
  • 블록 레벨 역할 영역에서 함수를 선언할 수 있습니다

  • 4
  • 함수 성명은 var과 유사하다. 즉, 전역 작용역이나 함수 작용역의 머리로 향상된다

  • 4
  • 동시에 함수 성명은 존재하는 블록급 작용역의 머리까지 향상시킬 수 있다

  • 상기 세 가지 규칙은 ES6의 브라우저에만 유효하고 다른 환경의 실현은 준수하지 않으며 블록급 역할 영역의 함수 성명을let으로 처리하는지 주의하십시오.


    이 세 가지 규칙에 따르면 브라우저의 ES6 환경에서 블록 레벨 역할 영역에서 성명하는 함수는 var 성명의 변수와 유사하다.

    //      ES6   
    function f() { console.log('I am outside!'); }
    
    (function () {
      if (false) {
        //         f
        function f() { console.log('I am inside!'); }
      }
    
      f();
    }());
    // Uncaught TypeError: f is not a function

    위의 코드는 ES6에 맞는 브라우저에서 모두 오류가 발생합니다. 왜냐하면 실제 실행된 코드는 아래의 코드이기 때문입니다.

    //      ES6   
    function f() { console.log('I am outside!'); }
    (function () {
      var f = undefined;
      if (false) {
        function f() { console.log('I am inside!'); }
      }
      f();
    }());
    // Uncaught TypeError: f is not a function

    환경이 초래하는 행위 차이가 너무 크다는 것을 감안하여 블록급 작용역에서 함수를 성명하는 것을 피해야 한다.

    //      
    {
        let a = 'hello';
        function f() {
            return a;
        }
        //f();  //hello
    }
    //f();      //hello

    권장: 필요하면 함수 성명문이 아니라 함수 표현식으로 써야 합니다.아래와 같다

    //      
    {
      let a = 'hello';
      let f = function () {
        return a;
      };
    }   //

    또한 주의해야 할 것은 ES6의 블록급 작용역은 함수를 성명하는 규칙을 허용하고 큰 괄호를 사용하는 상황에서만 성립되며, 큰 괄호를 사용하지 않으면 오류가 발생할 수 있습니다.

    //                              
    'use strict';
    if (true)
      function f() {}
    //    
    'use strict';
    if (true) {
      function f() {}
    }

    보충:

    function f() { console.log('I am outside!'); }
    (function () {
      if (false) {
        //         f
        function f() { console.log('I am inside!'); }
      }
      f();
    }());

    ES5에서 실행하면 "I am inside!",if에서 설명한 함수 f는 함수 헤더로 올라가기 때문에 실제 실행 코드는 다음과 같습니다.

    // ES5   
    function f() { console.log('I am outside!'); }
    (function () {
      function f() { console.log('I am inside!'); }
      if (false) {
      }
      f();
    }());

    좋은 웹페이지 즐겨찾기