만약에 면접에서 '클로저란 무엇인가요?' 라는 질문이 온다면, 뭐라고 답할까?

최근 프론트엔드 스터디를 하게 되면서, 면접용 대답과 실제 개념을 정리하고 발표하고 이를 깃북에 올려 공유하게 되었다.
이러한 작업이 많은 프론트엔드 개발자들에게 도움이 되었으면 하는 바람이다.
앞으로 이런 글이 깃북과 깃허브에 계속 올라갈 예정이니, 필요한 분들은 star를 눌러주시면 감사하겠습니다 ! 😇
FE-Tech-Interview | FE-CITYR0CK
[JavaScript] 클래스형 컴포넌트와 함수형 컴포넌트의 차이는 무엇일까요?
fe-cityr0ck.gitbook.io
GitHub - FE-CITYR0CK/FE-Tech-Interview
Contribute to FE-CITYR0CK/FE-Tech-Interview development by creating an account on GitHub.
github.com
그 중, 내가 발표했던 자바스크립트 클로저에 대한 내용이다.
면접용
자바스크립트에서 클로저란 함수가 선언될 때 생성된 렉시컬 환경을 기억하고, 함수가 실행되는 시점에도 그 환경에 접근할 수 있는 기능을 말합니다. 쉽게 말하면, 함수가 자신이 선언된 스코프의 변수에 계속 접근할 수 있도록 해주는 개념입니다.
예를 들어, 어떤 함수 안에서 또 다른 함수를 선언하고, 이 내부 함수가 외부 함수의 변수를 참조한다면, 이 내부 함수는 클로저가 됩니다. 중요한 점은 외부 함수가 실행을 끝내더라도, 내부 함수는 외부 함수의 변수에 접근할 수 있다는 것입니다.
클로저는 주로 상태를 유지하거나, 변수 값을 은닉하는 데 활용됩니다. 예를 들어, 카운터를 구현할 때 클로저를 사용하면 외부에서는 직접 접근할 수 없고, 내부 함수만 상태를 변경하거나 읽을 수 있습니다. 이런 방식으로 데이터 보호나 특정 로직 캡슐화가 가능합니다.
결국 클로저는 자바스크립트에서 변수를 더 안전하고 효율적으로 관리할 수 있게 도와주는 중요한 기능입니다.
꼬리 질문: 렉시컬 환경은 무엇인가요?
자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는데, 이를 렉시컬 스코프(정적 스코프)라고 합니다.
개념 설명
MDN는 클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다. 라고 정의하고 있습니다.
자바스크립트의 함수는 자신이 정의된 환경에 의해 결정된 상위 스코프의 참조, 즉 렉시컬 환경에 대한 참조를 자신의 내부 슬롯 [[Environment]]에 저장합니다.
클로저는 자바스크립트 고유의 개념은 아니기 때문에 ECMAScript 사양에는 등장하지 않습니다.

MDN의 예시 코드입니다. 다음과 같은 코드에서, displayName()은 클로저가 됩니다. 이유는 name은 init에 의해 생성된 지역 변수이지만, displayName() 함수가 이를 스코프체인을 타고 올라가 상위 스코프의 name변수에 접근 할 수 있기 때문입니다.
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() {
// displayName() 은 내부 함수이며, 클로저다.
console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
클로저의 핵심은 "상위 함수가 종료되었음에도, 하위 함수가 상위 함수의 변수를 참조할 수 있다"는 점입니다. 실제 클로저가 동작하기 위해서는 아래 코드와 같이 작성할 수 있습니다.
function init() {
var name = "Mozilla";
function displayName() {
console.log(name);
}
return displayName; // 함수 자체 반환
}
const myFunc = init(); // init은 종료되지만, 렉시컬 환경은 유지됨
myFunc(); // "Mozilla" 출력
자바스크립트의 모든 함수는 스코프 체인을 통해 상위 스코프를 기억하므로 이론적으로는 모든 함수가 클로저라고 할 수 있겠습니다! 하지만 만약 상위 스코프의 아무것도 참조하지 않는다면 그것은 메모리 낭비일 뿐 클로저라고 하기 어렵습니다.
function foo() {
const x = 1;
const y = 2;
function bar() {
const z = 3;
console.log(z);
}
return bar;
}
const bar = foo();
bar(); // 3은 출력하겠지만 이는 클로저는 아니다.
'frontend' 카테고리의 다른 글
| [JavaScript] task queue와 micro task queue (0) | 2024.11.01 |
|---|---|
| [frontend] 모노레포와 프론트엔드의 마이크로 아키텍쳐 (1) | 2024.10.14 |
| [frontend] HMR란 무엇이고 프론트엔드 개발에서 왜 중요할까? (1) | 2024.10.06 |
| [CSS] px, em, rem 차이와 rem이 유연한 페이지에 유리한 이유 (2) | 2024.09.30 |
| [JavaScript] npx는 npm을 어떻게 도와줄까? (1) | 2024.09.24 |