코어자바스크립트 강의정리 - 5. 클로저
클로저란 실행 컨텍스트 A 안에서 함수 B가 선언 되었을 때, 'A의 lexical environment와 내부함수 B의 조합에서 나타나는 특별한 현상' 이다.
대체 어떤 특별한 현상이 나타나는지 코드를 통해 살펴보자
위 코드에서 inner 함수는 outer함수의 lexical environment를 참조한다. 코드를 실행하면
outer 실행시작 - inner 실행시작 - inner안에 a변수가 없으므로 outer 에서 a 값을 찾아와 1을 더해 출력 - inner 컨텍스트 종료 - outer 컨텍스트 종료 순으로 이루어 진다. 딱히 특별한 현상이랄 것은 없어보인다.
코드를 살짝 바꾸어 다시 한번 살펴보자. 이번엔 inner에서 a를 콘솔로그하는대신 리턴하고 outer 함수 안에서도 inner을 실행하는대신 리턴한다.
코드가 실행되면 전역컨텍스트에 outer라는 변수안에 함수가 들어가고, outer2 라는 변수도 수집은 했는데 아직 실행 전이므로 값은 undefined 이다. 그리고 outer함수를 실행하면 outer 함수의 전역 컨텍스트가 실행되어 a에는 1 , inner에는 함수가 담긴다. 이후 outer함수의 결과값으로 inner 가 반환되고 inner 함수는 outer2에 담긴다. 여기서 특별한 현상이 나타난다. 원래대로라면 이후 outer실행컨텍스트가 종료되고 outer 내부 변수도 사라지지만, a를 참조하고 있는 inner 함수가 outer2에 살아있기 때문에 a의 참조 카운트는 0이 아니게 되고, 따라서 a의 변수 값은 사라지지 않고 남아있게 된다. 그 결과로 outer2 를 두번 콘솔로그 하면 ++a 한 값인 2와 한번 더 ++a 한 값인 3이 출력된다. 하지만 이후에도 전역 컨텍스트가 종료되기 전까지 a 변수는 계속 남아있다. 왜냐하면 outer2 변수가 지니고 있는 inner 함수 안에서 a를 계속 참조하고 있기 때문이다. 이때 a의 참조카운트를 0으로 만드려면 outer2 변수에 다른 값을 대입해서 참조의 연결 고리를 끊으면 된다.
위의 결과를 토대로 closure를 다시 정리하면 "컨텍스트A에서 선언한 변수 a를 참조하는 내부함수 B를 A의 외부로 전달할 경우, A가 종료된 이후에도 a가 사라지지 않는 현상"이 closure이다. 즉 함수 종료 후에도 사라지지 않는 변수를 만들 수 있는 것이다.
++후반부 내용 추가예정
댓글을 작성해보세요.