오늘은 Closure 클로저에 대해서 공부한 내용을 남기려 한다.
Closure 클로저에 대해서 이야기 하려면 우선 Scope 스코프에 대한 이해를 먼저 해야 한다.
MDN 의 정의를 한번 살펴보자
현재 실행되는 컨텍스트를 말한다. 여기서 컨텍스트는 값과 표현식이 "표현"되거나 참조 될 수 있음을 의미한다. 만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없다. 스코프는 또한 계층적인 구조를 가지기 때문에 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다.
Scope 스코프는 현재 실행되는 범위를 말한다.
변수 선언이 어디에 되어 있는가에 따라
그 변수를 어떤 위치에 있는 함수는 참조할 수 있고 없고가 달라지기 때문에
변수는 목적에 맞는 알맞은 위치에 선언되어야 한다.
그 범위는 지역스코프와 전역스코프로 나뉜다. 지역스코프는 함수 안이나 Curly bracket {} 의 단위로 구분된다.
Curly bracket {} 으로 구분되는 스코프를 Block scope 블록스코프라고 하고
함수로 구분되는 스코프를 함수스코프라고 한다.
이렇게 바깥과 구분되는 안쪽 스코프를 지역스코프라고 하고 구분되지 않은 가장 바깥쪽의 스코프를 전역스코프라고 한다.
이 그림을 참고해서 보면 가장 바깥에 있는 global scope 전역스코프와
그 안쪽에 있는 스코프들은 모두 local scope로 크게 나눌 수 있다.
안쪽에서 선언된 변수는 밖에서는 사용할 수 없지만 밖에서 선언한 변수는 안쪽에서 사용할 수 있다.
마치 경찰서 취조실 같이 한쪽에서는 볼 수 있고 한쪽에서는 못보는 것 처럼
안쪽에서는 밖을 볼 수 있고 밖에서는 안을 볼 수 없다.
이것이 클로저를 이해하는데 필요한 개념이다.
이 규칙을 이해해야 변수 선언의 위치에 따라 달라지는 결과 값들을 찾을 수 있다.
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.
Closure의 특징을 잘 표현한 것이 '외부함수의 변수에 접근이 가능한 내부함수' 라고 이해하면 좀 더 편하게 이해할 수 있다.
이 말을 다시 풀어보자면 함수 안에 다른 함수가 있다고 가정을 한다면
만약에 커피 값을 계산하는 함수를 만든다고 했을 때
아이스 3잔 모카 2잔을 계산한다면
function sum(a) {
let iceAme = 3500;
let moca = 4500;
return function (m) {
return iceAme*a + moca*m;
}
}
console.log(sum(3)(2)); // 19500
이런식의 함수를 사용해볼 수 있다. 예를 들어 생각해본 것이다.
이 함수는 함수 안에 함수가 있는 위에 있는 그림 형태와 비슷한 형태다.
여기서 계산식은 inner가 되고 바깥의 함수가 outer가 된다.
이렇게 한다면 계산식이 있는 inner 함수 안에는 가격 정보에 대한 변수 선언이
없기 때문에 그 밖에 있는 outer 함수에 선언된 가격정보를 참조하게 된다.
이렇게 내부함수가 외부함수의 변수에 접근하는 것을 클로저라고 한다.
접근 가능하면 클로저가 되는 것이다.
되는게 좋다 나쁘다기 보다 이 클로저의 장점이 있기 때문에 하나의 중요한
개념처럼 알아야 할 필요가 있다.
변수를 저렇게 outer에 선언을 했기 때문에 다른 함수나 전역스코프에 선언된 변수에 의해
변수의 값이 변하는 것을 방지할 수 있다.
outer에 있는 가격정보는 직접 함수를 고치기 전에는 외부에서 바꿀수는 없기 때문에
안정적인 변수 사용을 위해서 좋은 방법이 될 수 있다.
이렇게 오늘은 Scope와 Closure에 대해서 알아봤다.