JavaScript에서 클로저를 이해하는 데 도움이되는 간단한 안내서

JavaScript의 클로저는 많은 사람들이 고개를 끄는 데 어려움을 겪는 개념 중 하나입니다. 다음 기사에서는 클로저가 무엇인지 명확하게 설명하고 간단한 코드 예제를 사용하여 요점을 파악할 것입니다.

폐쇄 란 무엇입니까?

클로저는 내부 함수가 스코프 체인과 같은 외부 (포괄) 함수 변수에 액세스 할 수있는 JavaScript의 기능입니다.

클로저에는 세 가지 스코프 체인이 있습니다.

  • 중괄호 사이에 정의 된 변수 인 자체 범위에 액세스 할 수 있습니다.
  • 외부 함수 변수에 액세스 할 수 있습니다
  • 전역 변수에 액세스 할 수 있습니다

처음에는이 정의가 많은 전문 용어처럼 보일 수 있습니다!

그러나 실제로 폐쇄 란 무엇입니까?

간단한 폐쇄

JavaScript에서 간단한 클로저 예제를 보자.

함수 outer () {
   var b = 10;
   함수 inner () {
        
         var a = 20;
         console.log (a + b);
    }
   내부 반환;
}

여기에는 두 가지 기능이 있습니다.

  • 변수 b를 가지며 외부 함수를 반환하는 외부 함수 outer
  • a라는 변수가 있고 함수 본문 내에서 외부 변수 b에 액세스하는 내부 함수 inner

변수 b의 범위는 외부 함수로 제한되고 변수 a의 범위는 내부 함수로 제한됩니다.

이제 outer () 함수를 호출하고 outer () 함수의 결과를 변수 X에 저장하겠습니다. 그런 다음 outer () 함수를 다시 호출하여 변수 Y에 저장하겠습니다.

함수 outer () {
   var b = 10;
   함수 inner () {
        
         var a = 20;
         console.log (a + b);
    }
   내부 반환;
}
var X = outer (); // outer ()가 처음 호출되었습니다.
var Y = outer (); // outer ()가 두 번째 호출

outer () 함수를 처음 호출하면 어떻게되는지 단계별로 살펴 보겠습니다.

  1. 변수 b가 작성되고 범위가 outer () 함수로 제한되며 값이 10으로 설정됩니다.
  2. 다음 줄은 함수 선언이므로 실행할 것이 없습니다.
  3. 마지막 행에서 return inner는 inner라는 변수를 찾고이 변수 inner가 실제로 함수임을 확인하여 함수 inner의 전체 본문을 반환합니다.
    [return 문은 내부 함수를 실행하지 않습니다. 함수는 () 뒤에 오는 경우에만 실행되지만 오히려 return 문은 함수의 전체 본문을 반환합니다.]
  4. return 문으로 반환 된 내용은 X에 저장됩니다.
    따라서 X는 다음을 저장합니다.
     함수 inner () {
     var a = 20;
    console.log (a + b);
    }
  5. outer () 함수는 실행을 마치고 outer () 범위 내의 모든 변수가 더 이상 존재하지 않습니다.

이 마지막 부분은 이해하는 것이 중요합니다. 함수가 실행을 완료하면 함수 범위 내에 정의 된 모든 변수가 존재하지 않습니다.

함수 내부에 정의 된 변수의 수명은 함수 실행의 수명입니다.

이것이 의미하는 것은 console.log (a + b)에서 변수 b는 outer () 함수를 실행하는 동안에 만 존재한다는 것입니다. 외부 함수가 실행을 마치면 변수 b는 더 이상 존재하지 않습니다.

함수가 두 번째로 실행될 때 함수의 변수가 다시 생성되고 함수가 실행을 완료 할 때까지만 작동합니다.

따라서 outer ()가 두 번째로 호출 될 때 :

  1. 새로운 변수 b가 만들어지고 범위는 outer () 함수로 제한되며 값은 10으로 설정됩니다.
  2. 다음 줄은 함수 선언이므로 실행할 것이 없습니다.
  3. 내부 반환은 함수 내부의 전체 본문을 반환합니다.
  4. return 문으로 반환 된 내용은 Y에 저장됩니다.
  5. outer () 함수는 실행을 마치고 outer () 범위 내의 모든 변수가 더 이상 존재하지 않습니다.

여기서 중요한 점은 outer () 함수가 두 번째로 호출 될 때 변수 b가 새로 작성된다는 것입니다. 또한 outer () 함수가 두 번째로 실행을 완료하면이 새 변수 b는 다시 존재하지 않습니다.

이것이 가장 중요한 포인트입니다. 함수 내부의 변수는 함수가 실행 중일 때만 존재하며 함수 실행이 완료되면 존재하지 않습니다.

이제 코드 예제로 돌아가서 X와 Y를 살펴 보겠습니다. 실행시 outer () 함수가 함수를 반환하므로 변수 X와 Y는 함수입니다.

JavaScript 코드에 다음을 추가하여 쉽게 확인할 수 있습니다.

console.log (typeof (X)); // X는 함수 타입이다
console.log (typeof (Y)); // Y는 함수 유형입니다.

변수 X와 Y는 함수이므로 실행할 수 있습니다. JavaScript에서는 함수 이름 뒤에 X () 및 Y ()와 같이 ()를 추가하여 함수를 실행할 수 있습니다.

함수 outer () {
var b = 10;
   함수 inner () {
        
         var a = 20;
         console.log (a + b);
    }
   내부 반환;
}
var X = outer ();
var Y = outer ();
// outer () 함수 실행 끝
엑스(); // 처음 호출 한 X ()
엑스(); // 두 번째로 X ()를 호출했습니다.
엑스(); // X ()가 세 번째 호출
와이(); // Y ()가 처음 호출

X ()와 Y ()를 실행할 때 본질적으로 내부 함수를 실행합니다.

X ()가 처음 실행될 때 일어나는 일을 단계별로 살펴 보자.

  1. 변수 a가 작성되고 해당 값이 20으로 설정됩니다.
  2. JavaScript는 이제 a + b를 실행하려고합니다. 흥미로운 일이 있습니다. JavaScript는 방금 생성 한 이후 존재한다는 것을 알고 있습니다. 그러나 변수 b가 더 이상 존재하지 않습니다. b는 외부 함수의 일부이므로 외부 () 함수가 실행되는 동안에 만 b가 존재합니다. X ()를 호출하기 훨씬 전에 outer () 함수가 실행을 완료했기 때문에 외부 함수 범위 내의 변수가 더 이상 존재하지 않으므로 변수 b가 더 이상 존재하지 않습니다.

JavaScript는 이것을 어떻게 처리합니까?

폐쇄

내부 함수는 JavaScript의 폐쇄로 인해 둘러싸는 함수의 변수에 액세스 할 수 있습니다. 다시 말해, 내부 함수는 둘러싸는 함수가 실행될 때 둘러싸는 함수의 범위 체인을 유지하므로 둘러싸는 함수의 변수에 액세스 할 수 있습니다.

이 예에서, inner () 함수는 outer () 함수가 실행될 때 b = 10의 값을 유지하고 계속 유지 (폐쇄)했습니다.

이제는 범위 체인을 참조하고 외부 함수가 실행될 때 클로저 내에 b 값을 묶었 기 때문에 범위 체인 내에 변수 b 값이 있음을 알 수 있습니다.

따라서 JavaScript는 a = 20 및 b = 10을 알고 있으며 a + b를 계산할 수 있습니다.

위의 예제에 다음 코드 줄을 추가하여이를 확인할 수 있습니다.

함수 outer () {
var b = 10;
   함수 inner () {
        
         var a = 20;
         console.log (a + b);
    }
   내부 반환;
}
var X = outer ();
console.dir (X); //console.log () 대신 console.dir ()을 사용하십시오.

Chrome에서 Inspect 요소를 열고 콘솔로 이동하십시오. 요소를 확장하여 실제로 폐쇄 요소를 볼 수 있습니다 (아래의 마지막 세 번째 줄에 표시). outer () 함수가 실행을 완료 한 후에도 b = 10의 값이 Closure에 유지됩니다.

변수 b = 10은 클로저, 자바 스크립트의 클로저에 보존됩니다.

이제 처음에 본 클로저의 정의를 다시 살펴보고 더 이해가되는지 살펴 보겠습니다.

따라서 내부 함수에는 세 가지 범위 체인이 있습니다.

  • 자체 범위에 액세스-변수 a
  • 외부 함수의 변수-변수 b에 액세스
  • 정의 될 수있는 모든 글로벌 변수에 액세스

폐쇄 조치

폐쇄 지점을 유도하기 위해 다음 세 줄의 코드를 추가하여 예제를 보강 해 보겠습니다.

함수 outer () {
var b = 10;
var c = 100;
   함수 inner () {
        
         var a = 20;
         console.log ( "a ="+ a + "b ="+ b);
         a ++;
         b ++;
    }
   내부 반환;
}
var X = outer (); // outer ()가 처음 호출
var Y = outer (); // outer ()가 두 번째 호출
// outer () 함수 실행 끝
엑스(); // 처음 호출 한 X ()
엑스(); // 두 번째로 X ()를 호출했습니다.
엑스(); // X ()가 세 번째 호출
와이(); // Y ()가 처음 호출

이 코드를 실행하면 console.log에 다음 출력이 표시됩니다.

a = 20 b = 10
a = 20 b = 11
a = 20 b = 12
a = 20 b = 10

이 코드를 단계별로 검토하여 정확히 무슨 일이 일어나고 있는지 확인하고 실제로 폐쇄 된 부분을 확인하십시오!

var X = outer (); // outer ()가 처음 호출

outer () 함수가 처음으로 호출됩니다. 다음 단계가 수행됩니다.

  1. 변수 b가 작성되고 10으로 설정됩니다.
    변수 c가 생성되고 100으로 설정
    참고로이 b (first_time) 및 c (first_time)을 호출 해 보겠습니다.
  2. 내부 함수가 반환되고 X에 할당됩니다
    이때 변수 b는 내부 함수 범위 체인 내에 b = 10 인 클로저로 포함됩니다. 내부는 변수 b를 사용하기 때문입니다.
  3. 외부 함수는 실행을 완료하고 모든 변수가 존재하지 않습니다. 변수 b는 내부에 클로저로 존재하지만 변수 c는 더 이상 존재하지 않습니다.
var Y = outer (); // outer ()가 두 번째 호출
  1. 변수 b가 새로 만들어지고 10으로 설정 됨
    변수 c가 새로 작성됩니다.
    변수 b와 c가 존재하기 전에 outer ()가 한 번 실행되었지만 함수가 실행을 마치면 새로운 변수로 만들어집니다.
    이 b (second_time)과 c (second_time)을 자체 참조를 위해 호출하겠습니다.
  2. 내부 함수가 반환되고 Y에 할당됩니다
    이때 변수 b는 내부 함수 범위 체인 내에 b (second_time) = 10 인 클로저로 포함됩니다. inner는 변수 b를 사용하기 때문입니다.
  3. 외부 함수는 실행을 완료하고 모든 변수가 존재하지 않습니다.
    변수 c (second_time)는 더 이상 존재하지 않지만 변수 b (second_time)은 내부에 클로저로 존재합니다.

이제 다음 코드 줄이 실행될 때 어떤 일이 발생하는지 봅시다.

엑스(); // 처음 호출 한 X ()
엑스(); // 두 번째로 X ()를 호출했습니다.
엑스(); // X ()가 세 번째 호출
와이(); // Y ()가 처음 호출

X ()를 처음 호출하면

  1. 변수 a가 작성되고 20으로 설정
  2. a = 20의 값, b의 값은 클로저 값에서 나옵니다. b (처음 _ 시간)이므로 b = 10
  3. 변수 a와 b는 1 씩 증가합니다
  4. X ()는 실행을 완료하고 모든 내부 변수 (변수 a)가 존재하지 않습니다.
    그러나 b (first_time)은 클로저로 유지되므로 b (first_time)은 계속 존재합니다.

X ()가 두 번째로 호출되면

  1. 변수 a가 새로 만들어지고 20으로 설정됩니다.
     X ()가 처음 실행을 완료했을 때 존재하지 않기 때문에 변수 a의 이전 값은 더 이상 존재하지 않습니다.
  2. a = 20의 값
    b의 값은 클로저 값에서 가져옵니다 — b (first_time)
    또한 이전 실행에서 b 값을 1 씩 증가 시켰으므로 b = 11입니다.
  3. 변수 a와 b는 다시 1 씩 증가합니다
  4. X ()는 실행을 완료하고 모든 내부 변수 (변수 a)가 존재하지 않습니다.
    그러나 클로저가 계속 존재하므로 b (first_time)이 유지됩니다.

X ()가 세 번째로 호출되면

  1. 변수 a가 새로 만들어지고 20으로 설정됩니다.
    X ()가 처음 실행을 완료했을 때 존재하지 않기 때문에 변수 a의 이전 값은 더 이상 존재하지 않습니다.
  2. a = 20의 값, b의 값은 클로저 값-b (first_time)
    또한 이전 실행에서 b 값을 1 씩 증가 시켰으므로 b = 12입니다.
  3. 변수 a와 b는 다시 1 씩 증가합니다
  4. X ()는 실행을 완료하고 모든 내부 변수 (변수 a)가 존재하지 않습니다.
    그러나 클로저가 계속 존재하므로 b (first_time)은 유지됩니다.

Y ()를 처음 호출하면

  1. 변수 a가 새로 만들어지고 20으로 설정됩니다.
  2. a = 20의 값, b의 값은 클로저 값-b (second_time)에서 시작하므로 b = 10
  3. 변수 a와 b는 1 씩 증가합니다
  4. Y ()는 실행을 완료하고 모든 내부 변수 (변수 a)가 존재하지 않습니다.
    그러나 b (second_time)은 클로저로 유지되므로 b (second_time)은 계속 존재합니다.

끝 맺는 말

클로저는 처음에는 이해하기 어려운 JavaScript의 미묘한 개념 중 하나입니다. 그러나 일단 당신이 그것들을 이해하면, 다른 방법으로는 불가능했을 것입니다.

이 단계별 설명이 JavaScript의 클로저 개념을 실제로 이해하는 데 도움이 되었기를 바랍니다.

다른 기사 :

  • Javascript의 "자체 호출"기능에 대한 빠른 안내서
  • Javascript의 기능 범위와 블록 범위 이해
  • JavaScript에서 약속을 사용하는 방법
  • JavaScript로 간단한 Sprite 애니메이션을 작성하는 방법