
앞으로 인터뷰준비를 시작해보고자 한다...
코드만 쓸 줄 안다고 개발자가 아니기에....🥲
기본적인 원리, CS 공부도 병행해야겠다..!!
클로저를 검색하면 MDN에서 나오는 말은
클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생성 시 함수가 생성될 때마다 생성됩니다.
이러면 나같은 사람은 백퍼센트 이해를 못한다
이게 뭔말이야?
그리고 지피티한테 물어보면 정의를
클로저는 함수가 선언될 당시의 렉시컬 스코프(lexical scope)를 기억하고, 그 스코프 바깥에서 실행되더라도 해당 스코프에 접근할 수 있는 함수입니다.
이렇게 말해준다
MDN보다 조금 더 쉽긴한데 뭔가 느낌적인 느낌만 올뿐 명확하게 뭐다 이해는 불가하다
그럼 좀 더 쉽게 클로저에 대해 알아보면?
간단히 말하면
내부 함수가 외부 함수의 변수에 접근할 수 있게 해주는 기능이다
코드를 작성하면서 기능적으로는 몇번씩 써봤을 기능이다.
예를들면
function outer() {
let count = 0; // 외부 함수 변수
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
위 outer함수에서 선언된 count를 inner가 받아서 ++을 할 수 있는것이다.
count는 inner에서 선언된 변수는 아니지만 해당 스코프에 해당되기 때문에 쓸 수 있다.
라는 생각을 하게 된다
전역변수로
let count = 0;
을 선언하면 outer든, inner든 어디서든 가져다 쓸 수 있지않나?
여기서 클로저의 특징이자 장점이 나온다
만약 전역변수로 count가 선언되어 있다면 저 밑에서
count = 999;
를 선언해버린다면?
내가 inner에서 어떠한 작업을 해도 다시 재선언되어 버린다.
하지만
function outer() {
let count = 0; // 외부 함수 변수
return function inner() {
count++;
return count;
};
}
이렇게 outer안에 숨겨져 있다면 outer 외의 스코프에서는 접근이 불가능해져 재선언이 불가해지고, 실수로라도 데이터가 덮어써지는게 방지가 된다.
위 맥락과 비슷하게 해당 장점도 가지게 되는데
기존 es6이전에 해당하기만 한다.
for (var i = 1; i <= 3; i++) {
(function(n) {
setTimeout(() => console.log(n), 1000);
})(i);
}
기존 var를 통해 선언을 하게 되면 콜백함수 안에서 컨텍스트 유지가 되지 않아 해당 스코프안에서 클로저를 통해 기존 선언된 i의 값을 가져왔어야했다.
하지만 ES6로 넘어오면서 let이 생기고 개발자가 임의로 클로저를 통해 값을 할당하지 않아도
for (let i = 1; i <= 3; i++) {
setTimeout(() => console.log(i), 1000);
}
바로 이렇게 블록 스코프를 제공하기때문에 별도의 클로저를 생성하지 않아도 된다.
개발자의 편의가 증가되었다~!
다음으로는 상태 유지가 된다는 장점이다
일반적으로 함수는 호출이 끝나면 지역변수도 사라지며 메모리에서도 날라간다.
하지만 함수 호출이 끝나더라도 해당 값이 필요할때가 있다.
그런 경우에 클로저를 통해 내부 함수에서 내부 함수의 변수를 참조하고 있으면 메모리에서 날라가지 않고 계속해서 참조할 수 있다.
function createCounter() {
let count = 0;
return () => {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
counter 는 함수가 끝나도 계속 유지되어 호출할때마다 누적된값을 반환한다.
그래서 면접 답변 형식으로 대답한다면?
클로저는 함수가 선언될 당시의 스코프를 기억해서,
함수 실행이 끝난 뒤에도 그 스코프 안의 변수에 접근할 수 있는 함수입니다.
예를 들어, 일반적으로 함수가 끝나면 지역 변수는 사라지지만,
클로저를 사용하면 그 변수를 내부 함수가 계속 참조하고 있기 때문에
이후에도 값이 유지됩니다.
그래서 버튼 클릭 횟수를 저장하는 카운터나,
한 번 계산한 결과를 다시 활용하는 캐싱 로직처럼
상태를 기억해야 하는 기능을 구현할 때 자주 사용됩니다.
이런 방식으로 클로저는 데이터 은닉, 상태 유지, 비동기 로직에서의 컨텍스트 유지 같은 문제를 해결할 수 있습니다.
설명 예시를 보면 언젠가 한번씩은 해봤던거 같은데
이렇게 말로 답하는게 어렵다니...
앞으로 열심히 공부해야겠다...!