2023. 1. 19. 16:09ㆍ기술면접 준비
1) 클로저(Closure)에 대해 설명해주세요.
클로저란?
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.
위 정의에서 말하는 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란
내부 함수가 선언됐을 때의 스코프를 의미한다.
즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.
이를 조금 더 간단히 말하면,
클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있겠다.
클로저에 의해 참조되는 외부함수의 변수 즉 outerFunc 함수의 변수 x를 자유변수(Free variable)라고 부른다. 클로저라는 이름은 자유변수에 함수가 닫혀있다(closed)라는 의미로 의역하면 자유변수에 엮여있는 함수라는 뜻이다.
실행 컨텍스트의 관점에 설명하면, 내부함수가 유효한 상태에서 외부함수가 종료하여 외부함수의 실행 컨텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성 객체(Activation object)(변수, 함수 선언 등의 정보를 가지고 있다)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프 체인을 통해 참조할 수 있는 것을 의미한다.
클로저가 필요한 이유
1. 전역변수를 줄일 수 있다.
전역변수는 예상치 못한 Side Effect를 일으킬 수 있기에 최대한 줄이는 것이 좋다.문에 최대한 전역변수를 줄여서 코딩해야한다.
하지만 프로그램 구현 시 함수 하나에 사용하는 전역변수가 필요한 순간이 있다. 이럴 때 클로저가 유용하게 사용된다.
// Counter 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick)
let count = 0
function handleCilck(){
count++
return count
}
//위와 같은 경우에 count를 전역변수로 사용해줘야 count가 증가를 해줄 수 있음
//이럴경우 클로져를 사용해서 해결할 수 있다.
// Counter Closure 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick())
function handleCilck(){
let count = 0
return function (){
count++
return count
}
}
// 위와 같이 작성해 준다면 외부함수(handleClick)의 lexical environment를 참조하는 함수를
// btn의 콜백함수로 이용해 전역객체 없이 구현할 수 있다.
2. 비슷한 형태의 코드를 재사용률을 높일 수 있습니다.
// 새로운 태그를 만들 수 있는 함수 Closure 구현
const order = (food) => {
console.log(food + "을(를) 주문하셨습니다.");
return function (drink) {
return drink + "을(를) 추가로 주문하셨습니다."
}
}
const orderBurger = order("햄버거");
const orderPizza = order("피자");
console.log(orderBurger("콜라"));
console.log(orderPizza("사이다"));
//<b><i>This is my content!</i></b>
인자에 open,close,content를 한번에 다 받는다면,This is my content! 와 같은 값을 출력을 하고 싶을 때 가독성이 떨어질 수 있다.
하지만 클로져로 구현하면 코드의 가독성도 좋은 재사용하기 편한 코드를 구현할 수 있음.
2) 렉시컬 환경(Lexical Environment)에 대해 설명해주세요.
👍 클로저란?
클로저에 대해 MDN은 아래와 같이 정의하고 있습니다.
“A closure is the combination of a function and the lexical environment within which that function was declared.”
클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.
✔ 렉시컬 환경(Lexical Environment)
자바스크립트에선 실행 중인 함수, 코드 블록 {...}, 스크립트 전체는 렉시컬 환경(Lexical Environment)이라 불리는 내부 숨김 연관 객체(internal hidden associated object)를 갖습니다.
렉시컬 환경 객체는 두 부분으로 구성됩니다.
- 환경 레코드(Environment Record) : 모든 지역 변수를 프로퍼티로 저장하고 있는 객체입니다. this 값과 같은 기타 정보도 여기에 저장됩니다.
- 외부 렉시컬 환경(Outer Lexical Environment)에 대한 참조 : 외부 코드와 연관됨
렉시컬 변화를 나타내는 이미지
위의 이미지는 코드가 한 줄, 한 줄 실행될 때마다 전역 렉시컬 환경이 어떻게 변화하는지 보여줍니다.
- 스크립트가 시작되면 스크립트 내에서 선언한 변수 전체가 렉시컬 환경에 올라갑니다(pre-populated).
- 이때 변수의 상태는 특수 내부 상태(special internal state)인 'uninitialized’가 됩니다. 자바스크립트 엔진은 uninitialized 상태의 변수를 인지하긴 하지만, let을 만나기 전까진 이 변수를 참조할 수 없습니다.
- let phrase가 나타났네요. 아직 값을 할당하기 전이기 때문에 프로퍼티 값은 undefined입니다. phrase는 이 시점 이후부터 사용할 수 있습니다.
- phrase에 값이 할당되었습니다.
- phrase의 값이 변경되었습니다.
아직까진 어려운 게 없어 보이네요. 지금까지 배운 내용을 요약해 봅시다.
- 변수는 특수 내부 객체인 환경 레코드의 프로퍼티입니다. 환경 레코드는 현재 실행 중인 함수와 코드 블록, 스크립트와 연관되어 있습니다.
- 변수를 변경하면 환경 레코드의 프로퍼티가 변경됩니다.
👍 렉시컬 환경은 명세서에만 존재합니다.
'렉시컬 환경’은 명세서에서 자바스크립트가 어떻게 동작하는지 설명하는 데 쓰이는 ‘이론상의’ 객체입니다. 따라서 코드를 사용해 직접 렉시컬 환경을 얻거나 조작하는 것은 불가능합니다.
자바스크립트 엔진들은 명세서에 언급된 사항을 준수하면서 엔진 고유의 방법을 사용해 렉시컬 환경을 최적화합니다. 사용하지 않는 변수를 버려 메모리를 절약하거나 다양한 내부 트릭을 써서 말이죠.
https://velog.io/@wngud4950/%ED%81%B4%EB%A1%9C%EC%A0%80Closure%EB%9E%80
https://whales.tistory.com/109
클로저 이번에 재대로 이해하기
자바스크립트를 공부하게 되면 한 번쯤은 들어보게 되는 단어가 '클로저'입니다. 하지만 막상 클로저를 설명하려고 하면 어렴풋이 개념은 알고 있어도 쉽게 설명을 하지 못하는 경우가 많습니
whales.tistory.com
'기술면접 준비' 카테고리의 다른 글
1. javascript 질문과 답안 (6) (0) | 2023.01.26 |
---|---|
자바 스프링 면접 질문 (0) | 2023.01.19 |
1. javascript 질문과 답안 (4) (0) | 2023.01.16 |
1. javascript 질문과 답안 (3) (0) | 2023.01.15 |
1. javascript 질문과 답안 (2) (0) | 2023.01.11 |