클로저란?
클로저란, 자바스크립트의 고유 개념이 아니라 함수형 프로그래밍 언어에서 사용되는 중요한 특성이다.
클로저는 반환된 내부함수가 자신이 선언되었을 때 환경(렉시컬 환경) 스코프를 기억하여, 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 뜻한다.
렉시컬 환경 : 내부 함수가 선언되었을 때의 스코프
함수와 함수가 선언된 어휘적(Lexical) 환경의 조합
클로저는 함수를 지칭하고 또 그 함수가 선언된 환경과의 관계라는 개념이 합쳐진 것이다.
클로저의 핵심은 스코프를 이용하여, 변수의 접근 범위를 폐쇄하는 것에 있다.
외부함수 스코프에서 내부함수 스코프로 접근 불가능하다.
내부함수에서는 외부함수 스코프에서 선언된 변수에 접근 가능하다.
따라서 내부 함수는 외부 함수에 선언된 변수에 접근 가능하다.
함수가 호출되는 환경과는 별개로, 기존에 선언되어 있던 환경을 기준으로 변수를 조회한다.
외부함수의 실행이 종료된 후에도, 클로저 함수는 외부함수의 스코프, 즉 함수가 선언된 어휘적 환경에 접근을 할 수 있다.
외부 함수 스코프가 내부함수에 의해 언제든지 참조될 수 있다.
클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있다.
상위 스코프의 식별자를 포함하여 쓰여있는 내부 함수 코드 자체를 어휘적(Lexical Environment)라고 부를 수 있다.
클로저는 내부함수가 외부함수의 맥락(Context)에 접근을 할 수도 있다.
내부함수가 상위 스코프의 식별자를 참조하고 있고, 그 내부함수를 그 상위 스코프 바깥에서 사용했을 때, 그 상위 스코프의 식별자를 수정할 수 없는 형태이다.
즉, 함수가 정의되었던 위치에서 상위 스코프 식별자를 기억하고 있는 형태이다.
그래서 중첩함수 뿐만 아니라 내부함수가 외부 스코프에 접근할 수 있는 형태의 클로저도 존재한다.
아래의 두 가지 예시
// (1) 클로저를 만드는 형태, 중첩함수
function outer() {
let x = 10;
return function inner(y) { // inner 함수는 클로저 함수
return x = x + y;
}
}
let answer = outer(); // 한번의 외부함수 호출로, a 변수는 inner 함수를 참조한다.
answer(5); // 15;
answer(5); // 20;
answer(5); // 30;
// (2) 클로저를 만드는 형태, 전역에 선언한 변수를 박스 안에서 함수로 정의
let globalFunc;
{
let x = 10;
globalFunc = function(y) { // globalFunc 함수는 클로저이다.
return x = x + y;
}
}
globalFunc(5); // 15;
globalFunc(5); // 20;
globalFunc(5); // 25;
클로저는 언제나 함수를 리턴하는 함수가 아니다.
함수를 언제나 리턴하는 함수가 아니라, 내부 함수(inner)가 상위 스코프(outer)의 식별자를 참조하고 있고 그 상위 스코프(outer) 바깥에서 사용했을 때 그 상위 스코프(outer)의 식별자를 수정할 수 없는 형태이다.
실제로 함수를 리턴하는 함수의 클로저 사례가 아주 많지만, return 없이 클로저가 발생하는 경우도 있다.
(function () {
var count = 0;
var button = document.createElement("button");
button.innerText = "click";
button.addEventListner("click", function() {
console.log(++count, "times clicked");
});
document.body.appendChild(button);
}) ();
// 별도의 외부 객체인 DOM의 메서드 (addEventListener)에 등록할 handler 함수 내부에서 지역변수를 참조
지역 변수를 참조하는 내부 함수를 외부에 전달했기에 클로저는 맞지만, 외부로 전달이 항상 return을 의미하는 것이 아니다.
클로저는 외부함수와 내부함수에 의해서 스코프가 분리된 함수도 있다.
외부함수와 내부함수에 의해 스코프가 분리된 클로저도 있다.
박스와 내부함수에 의해 스코프가 분리된 클로저도 있다.
➠ 클로저는 특정 상황에서 발생하는 현상이고, 함수는 이 현상을 나타나기 위한 조건에 해당한다고 보면 된다.
클로저의 장점
데이터를 보존할 수 있다.
클로저 함수는 외부 함수의 실행이 끝나더라도 외부 함수 내 변수를 사용할 수 있다.
클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 하는 폐쇄성을 갖는다.
정보의 접근 제한(캡슐화)
클로저 모듈 패턴을 사용해 객체에 담아 여러 개의 함수를 리턴하도록 만든다.
이러한 정보의 접근을 제한하는 것을 캡슐화라고 한다.
모듈화에 유리하다.
클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용하고 보존할 수 있다.
이와 같이 함수의 재사용성을 극해화 함수 하나를 독립적인 부품의 형태로 분리한느 것을 모듈화라고 한다.
클로저를 통해 데이터와 메소드를 묶어다닐 수 있기에 클로저는 모듈화에 유리하다.
function order(food) {
console.log(`${food}을(를) 주문하셨습니다.`);
return function (drink) {
console.log(`${drink}을(를) 추가로 주문하셨습니다.`);
}
}
const orderBurger = order("햄버거");
const orderPizza = order("피자");
orderBurger("콜라");
orderPizza("사이다");
레퍼런스
'취준적인' 카테고리의 다른 글
React의 Virtual DOM (0) | 2023.02.24 |
---|---|
함수 선언식과 함수 표현식의 차이 (0) | 2023.02.13 |
자바스크립트가 유동적인 언어인 이유 (0) | 2023.02.12 |
Promise를 사용한 비동기 통신, Async · Await 비동기 통신의 차이점 (0) | 2023.02.12 |
취업에 있어 우리가 길잡이로 가져야 할 태도 (0) | 2023.02.10 |
댓글