클로저(Closure)
함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.
- 어휘적 범위 지정 (Lexical scoping)
function init() {
var name = "test";
function displayName() {
console.log(name);
}
displayName();
}
init();
여기서 주의할 점은 displayName() 내부에는 자신만의 지역 변수가 없다는 점이다. 하지만 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init() 에서 선언된 변수 name에 접근할 수 있다. 만약 displayName() 이 자신만의 name 변수를 가지고 있었다면, name 대신 this.name을 사용했을 것이다.
test
그렇다면 클로저를 알아보자.
function makeAdder(x) {
var y = 1;
return function(z) {
y = 100;
return x + y + z;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
// 클로저에 x와 y의 환경이 저장됨
console.log(add5(2));
console.log(add10(2));
// 함수 실행 시 클로저에 저장된 x, y값에 접근하여 값을 계산
복잡해 보이지만 하나하나 뜯어보면 답을 알 수 있다.
이 예제는 단일 인자 x를 받아서 새 함수를 반환하는 makeAdder(x)를 정의한다. 또 반환되는 함수는 단일인자 z를 받아서 x와 y와 z의 합을 반환한다.
add5와 add10은 둘 다 클로저이다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다. 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5이지만, add10의 맥락적 환경에서 x는 10이다. 또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.
따라서 다음과 같은 값을 출력한다.
107 // (x:5 + y:100 + z:2)
112 // (x:10 + y:100+ z:2)
위와 같은 방식으로 자바스크립트에는 없는 캡슐화라는 개념을 구현할 수 있고, 정보 은닉과 캡슐화가 가져다주는 이점들을 얻을 수 있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
'코딩 > 정말 나는 잘 알고 있을까?' 카테고리의 다른 글
REST API가 뭐야? (feat. GET, POST, PUT, DELETE) (0) | 2022.08.02 |
---|---|
CSS 기본 지식 (0) | 2022.08.02 |
호이스팅(Hoisting)이 뭐야? (0) | 2022.08.02 |
브라우저는 어떻게 동작하는가? (0) | 2022.08.02 |
Create React App, Next.js, Gatsby (0) | 2022.08.02 |