JS의 패키지 폐쇄 및 그 중요성

9311 단어 tutorialjavascript
개발자가 자바스크립트 코드를 작성할 때의 주요 기능 중 하나는 아마도 그들이 가장 잘 알지 못하는 것일 것이다.이것은 단지 코드를 직접 작성하는 사람이 없기 때문일 수도 있고, 심지어는 그들의 코드가 중단되지 않은 원인이 이 기능과 관련이 있는지도 모른다.
그런데 이게 무슨 특징이죠?
좋아요.그것은 사실상 하나의 기능이 아니다.이것은 JavaScript가 어떻게 구축되고 어떻게 컴파일되고 실행되고 실행되는지의 부작용입니다.예를 들자.
브라우저 개발 도구에서 다음 명령을 실행하면
var age = 14;

function getOlder() {
  var age = 14;
  age++;
};

getOlder();

console.log(`I am ${age} years old.`); // <-- ???
  • 끊어짐(🤷)
  • 인쇄I am 14 years old.
  • 인쇄I am 15 years old.
  • 정답은 2: I am 14 years old.!그런데 왜죠?

    실행 상황 설명


    AST(추상적 문법 트리)와 JS가 어떻게 구상되었는지에 대해 많은 중요한 정보가 있습니다. 여기는 연구를 하지 않지만 독자들이 참고할 수 있습니다(참고 문헌을 보십시오!).이렇게 생각하면:
    브라우저에서 실행되는 VM(예: Chrome의 V8)에서 코드를 실행하면 각 변수의 이름이 지정됩니다.변수를 해석하는 과정은 필수적이기 때문에 성명과 정의된 변수를 사용할 때 코드를 파괴하지 않습니다.코드가 올바르게 정의되지 않은 함수나 변수에 액세스하려고 하면Uncaught ReferenceError: yourVariable is not defined .

    마크 델루이가 Unsplash에 있는 사진.

    수동 해석 변수


    명명 처리된 결과에 액세스할 수 있는 경우 원본 코드는 다음과 유사한 코드로 대체적으로 변환됩니다.
    var global__age = 14;
    
    function global__getOlder() {
      var getOlder__age = 14;
      getOlder__age++;
    };
    
    global__getOlder();
    
    console.log(`I am ${global_age} years old.`); // --> 'I am 14 years old.'
    
    현재 출력은 I am 14 years old. 의미가 있는 거죠?추가된 접두사는 명명 해석이 발생할 때 모든 변수와 방법의 패키지와 관련이 있습니다.이 코드에는 다음과 같은 2개의 패키지가 있습니다.
  • global
  • getOlder
  • getOlder 패키지는 global 패키지에 있지만 getOlder() 원시 함수 내의 변수는 괄호 안에서만 접근할 수 있음을 알 수 있습니다.
    따라서 getOlder__age 변수는 global__getOlder() 함수에만 존재하는 것이 더욱 의미가 있다.검증의 좋은 예는 함수 내부, 외부에서 변수를 기록하는 것입니다.
    var global__age = 14;
    
    function global__getOlder() {
      var getOlder__age = 14;
      getOlder__age++;
    };
    
    global__getOlder();
    
    console.log(`I am ${getOlder__age} years old.`); // --> Error!
    
    결과는 Uncaught ReferenceError: getOlder__age is not defined로 출력되었습니다. 이름 해석 global 이 없는 폐쇄 변수는 getOlder__age 에 유효합니다.

    근데 범위는요?


    함수를 만들 때 패키지를 닫는 방식은 작용역과 같습니다.그 중의 모든 변수와 함수는 외부에 있는 것이 아니라 모든 하위 함수에 접근할 수 있다.
    작용역과 폐쇄역은 거의 같지만 두 번째 작용역은 약간의'초능력'이 있다. 폐쇄역에서 생성되고 공개된 변수와 함수는 여전히 폐쇄 밖에서 작동한다. 설령 작용역이 존재하지 않는다 하더라도.이것은 이 두 개념 사이의 매우 긴밀한 경계이다.
    비록 이러한 공개된 항목은 패키지 내의 다른 변수/함수에 의존하지만 공개되지 않은 것도 옳다.

    패키지 닫기 및 역할 영역


    이 두 개념 간의 차이를 설명하기 위해서 우리는 위와 거의 같은 예시를 사용하고 약간의 변경만 하였으며 아래의 코드는 하나의 출발점이다
    function main() {
      var age = 14;
    
      function getOlder() {
        age++;
    
        console.log(`I am ${age} years old now.`); // --> 'I am 15 years old.'
      };
    
      getOlder();
    };
    
    main();
    
    이 예에서 함수getOlder()main() 함수에서 호출되고 인쇄I am 15 years old now.됩니다. 맞습니까?변수agemain 범위 내에서 getOlder() 함수를 통해 접근할 수 있습니다.getOlder() 함수를 외부 "세계"로 되돌아와 세 번 실행합니다. 다음 예시와 같이 결과는 어떻습니까?
    function main() {
      var age = 14;
    
      function getOlder() {
        age++;
    
        console.log(`I am ${age} years old now.`); // <-- ???
      };
    
      return getOlder;
    };
    
    var getOlder = main();
    
    getOlder(); // <-- ???
    getOlder(); // <-- ???
    getOlder(); // <-- ???
    
  • 없습니다.코드가 중단됩니다.
  • 3회I am 15 years old now.
  • age 변수의 값은 15 에서 16 으로 증가합니다.
  • 정답은 정답입니다.
    그런데 왜 이러지?
    패키지를 만들 때마다 모든 변수와 함수는 그 상태에 저장됩니다.17 함수의 실행이 끝난 후에도 상응하는 패키지 상태는 유효하고 변수와 함수를 저장합니다!
    아마도 가장 경외스러운 부분은 main() 변수가 age 패키지에서 잃어버려서 패키지 밖에서 접근할 수 없습니다!코드의 다음 부분에서 이 변수main()에 접근하려고 시도하면 앞에서 논의한 age 오류가 발생합니다. 이 변수는 Uncaught ReferenceError: age is not defined 함수 밖에 존재하지 않기 때문입니다!

    Maria Teneva가 Unsplash에서 찍은 사진.

    총결산


    폐쇄와 범위 개념 사이의 놀라운 차이에 대해 논의했다.
  • 클라이언트가 항상 변수와 함수를 저장하는 상태
  • 패키지를 만드는 함수 끝에 이 변수/함수를 되돌려줌으로써 그 중 일부, 전부 또는 그 하나를 공개할 수 있다
  • 심지어 같은 이름으로 패키지 내의 일부 외부 변수/함수를 재정의할 수 있으며, 가상 컴퓨터 컴파일러는 실행 중 오류와 이름 충돌을 피하기 위해 그것을 처리할 것이다
  • 이 문장은 너에게 유용하니?제가 설명하다가 뭘 놓쳤나요?채팅방에서 알려주거나 메시지를 보내주세요!

    공구서류

  • Article about AST and how JS works from Lachezar Nickolov
  • MDN Article about Closures
  • GitHub Mirror repo of V8
  • 좋은 웹페이지 즐겨찾기