[JS]자바스크립트 클로저(Closure)

KBS·2022년 1월 15일
0

JS

목록 보기
8/9


자바스크립트에서 헷갈리는 문법. 클로저에 대해 알아보려고 한다.

구글링을 해보아도 정의를 통해 이해 하는 것은 쉽지 않기에 예시를 통해 정리하려고 한다.

클로저를 이해하기 전에 알아야할 내용. 스코프 체인!
거의 클로저를 알기위한 핵심 내용이라고 봐도 될것 같다.

스코프란?

스코프는 함수단위로 이루어져 있다.
안쪽 함수에서부터 원하는 값이 있는지 없는지를 찾기 시작하여 없다면 바깥쪽을 찾고, 최종적으로 전역 스코프까지 탐색하게 된다.
이를 스코프 체인이라고 한다.

그래서 클로저란?

"외부 함수의 실행이 끝나고 외부 함수가 소멸된 이후에도 내부 함수가 외부 함수의 변수에 접근할 수 있는 구조"
좀더 쉽게 말하면
"자신의 고유 스코프를 가진 상태로 소멸하지 않고 외부 함수에 의해 호출되는 함수를 만드는것"

예제1

let num =1;

function foo() {
	let num = 2;
    
    function bar() {
    	console.log(num);
    }
    return bar;
}

let baz = foo();
baz();

위의 코드를 실행시키면 2가 정상적으로 출력된다.
"foo() 함수는 리턴되어 사라진 후에 내부 함수 bar가 생성되는 것인데, 여전히 내부함수가 bar가 외부함수인 foo의 지역변수에 접근할 수 있을까?"
라는 질문을 보면 좀 더 이해가 쉬울 것이다.
위에 대한 답은 . 가능하다.

외부함수가 리턴되어 사라져야 하는데 사라지지 않고 내부함수의 참조로 인해 값을 유지하게 되는것을 클로저라고 부른다.

예제2

let d = 'X';

function outer(){
	let a = 1;
    let b = 'B';
    
    function inner () {
    	let a = 2;
        console.log(d); // inner함수 안에 d 가 없으니 outer함수에서 찾고, 거기에도 없으니 전역공간까지 탐색하여 d 값 'X'를 출력한다. (스코프 체인)
        console.log(b); // 마찬가지로 inner함수 안ㅇ ㅔb가 없으니 바깥 함수인 outer에서 b값 'B'를 출력한다.
    }
}
		return inner();
        
let someFun = outer();
someFun();

위 코드를 실행하면 생성한 시점의 스코프체인을 계속 들고있다.
이를 클로저라고 한다.
클로저로 인해 outer()가 실행된 다음에도 inner()가 outer() 에 대한 스코프를 들고 있다.

예제3

function makeCounter() {
	let num = 0; //은닉화
    
    return function () {
    	return num++;
    }
}

let counter = makeCounter();

console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2

makeCounter함수 안의 return 안의 함수(내부함수)
내부함수에서 외부함수의 변수 즉 num에 접근한다.
이렇게 생성된 이후에 계속 기억하고 있고
num의 저장된 값을 임의로 다른 값으로 수정할 수 있는가?

정답은 아니다.
num에 접근해서 값을 변경할 수 없으며 오직 return의 num++를 통해서만
가능하기에 은닉화에 성공하였다.

클로저 장점

전역 변수의 남용을 막을 수 있고 변수 값을 은닉하는 용도로도 사용할 수 있다.

사용시 주의할점.

클로저로 참조하는 변수는 프로그램 종료 시까지 계속 메모리에 할당되어 있기 때문에, 메모리 누수로 인해 성능 저하의 원인이 될 수 도 있으니 신중하게 사용해야 한다.

참조.
https://hanamon.kr/javascript-%ED%81%B4%EB%A1%9C%EC%A0%80/
https://edu.goorm.io/learn/lecture/557/%ED%95%9C-%EB%88%88%EC%97%90-%EB%81%9D%EB%82%B4%EB%8A%94-node-js/lesson/21731/%ED%81%B4%EB%A1%9C%EC%A0%80

profile
FE DEVELOPER

0개의 댓글