|
학습 전 |
학습 후 |
클로저란 무엇이고 왜 중요한가요? |
클로저는 다른 스코프에서 선언한 변수에 접근 가능 한 상태를 말합니다. 변수를 은닉할 수 있다는 점이 중요합니다. |
클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합입니다.
또한 외부함수보다 중첩함수가 더 오래 유지되는 경우, 중첩 함수는 이미 생명주기가 종료한 외부 함수의 변수를 참조할 수 있습니다.
변수를 은닉할 수 있다는 장점이 있어서 중요합니다. |
자바스크립트에서는 클로저가 어떻게 생성이 되나요? |
|
클로저는 함수가 다른 함수의 내부에 정의되고, 해당 함수가 외부 함수의 변수에 접근할 때 생성됩니다.
내부함수는 외부함수의 렉시컬 환경에 대한 참조를 가지며, 이 참조는 함수 객체의 [[Environment]] 슬롯에 저장됩니다.
외부함수가 실행을 마치고 반환되어도 내부 함수는 여전히 외부 함수의 렉시컬 환경을 기억하고 있기 때문에 외부 함수의 변수에 접근 할 수 있습니다. |
클로저는 어떤 상황에서 유용하게 사용될 수 있나요? 예시를 들어주세요. |
|
상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용합니다.
대표적인 예시로는 클릭하면 증가하는 counter함수가 있습니다. count = 0 변수를 함수 외부에 선언하고 counter 함수는 클릭하면 count 값이 1씩 증가한다면 count 변수가 외부에서 변질될 우려가 있으므로 클로저를 사용하여 counter 함수에 count 변수를 선언하고 상태를 관리하는 것이 변질될 우려가 없도록 합니다. |
다음 함수가 클로저를 사용하는지, 사용한다면 외부에서 이 클로저를 어떻게 호출할 수 있는지 설명해주세요.
```js function outerFunction() { let outerVar = 'I am an outer variable';
function innerFunction() { console.log(outerVar); }
return innerFunction; } ``` |
|
const closureFunction = outerFunction();
closureFunction()
// 클로저는 함수와 그 함수가 정의된 렉시컬 환경 간의 관계이며 함수가 반환된 이후에도 유지되어야합니다.
예를들어 outerFunction을 직접 호출하면 innerFunction은 그저 outerFunction 내부에서 실행되는 것으로 인식되고 클로저의 역할을 수행하지 않습니다.
innerFunction이 클로저로 사용되려면 innerFunction의 [[Environment]]에 outerFunction이 저장되고 closureFunction이 실행됨으로 렉시컬 환경이 참조되며 클로저가 작동합니다. |
간단하게 클로저를 직접 구현해주세요. |
|
function createCounter() { let count = 0; // 클로저 내부에서 유지되는 변수
function increment() { count++; console.log(count); }
return increment; }
const counter = createCounter(); // 클로저 생성
// 1초마다 클로저를 호출하여 카운터를 증가시킴 setInterval(counter, 1000); |
Closure를 사용할 때 주의해야 할 사항은 무엇일까요? 메모리 누수(Memory Leak)를 피하기 위해 어떤 조치를 취해야 할까요? |
사용하지 않는 변수는 삭제 처리를 해주어야합니다. |
클로저를 사용할 때 주의해야 할 몇 가지 사항과 메모리 누수를 피하기 위한 조치는 다음과 같습니다:
- 메모리 누수 주의:
- 가장 중요한 것은 클로저가 메모리 누수를 일으킬 수 있다는 점입니다. 클로저는 함수와 그 함수가 정의된 스코프의 변수에 대한 참조를 유지하므로, 클로저를 오랫동안 유지하거나 필요 이상으로 많이 생성하면 메모리 누수가 발생할 수 있습니다.
- 불필요한 클로저 생성 피하기:
- 불필요한 클로저 생성을 피하기 위해 클로저를 만들 때 주의해야 합니다. 함수가 외부 변수를 사용하지 않는 경우 클로저를 생성하지 않는 것이 좋습니다.
- 정기적으로 해제:
- 클로저가 더 이상 필요하지 않은 경우 (예: 이벤트 핸들러의 등록을 해제할 때), 클로저에 대한 참조를 해제해야 합니다. 이것은 클로저가 참조하는 외부 변수와 클로저 자체에 대한 참조를 모두 해제해야 함을 의미합니다. JavaScript에서는 불필요한 참조를 제거하기 위해 가비지 컬렉션을 활용합니다.
- 적절한 범위(scope)에서 사용:
- 클로저를 생성할 때, 최대한 제한된 스코프에서 생성하고 사용하는 것이 좋습니다. 필요한 데이터만 포함된 스코프에서 클로저를 생성하면 메모리 누수 가능성이 줄어듭니다.
- 이벤트 핸들러에서 주의:
- 이벤트 핸들러에서 클로저를 사용할 때, 이벤트 핸들러가 자주 호출되는 경우 메모리 누수 가능성이 높아집니다. 이 경우 이벤트 핸들러 등록을 취소하거나 필요한 데이터만 클로저에 유지하도록 조치를 취해야 합니다.
- 자동 해제 기법:
- 일부 상황에서는 자동 해제 기법을 사용하여 메모리 누수를 방지할 수 있습니다. WeakMap을 활용하여 클로저에서 관리하는 데이터를 관리하고, 해당 데이터가 필요 없어지면 WeakMap에서 자동으로 해제되도록 만들 수 있습니다.
|
클로저와 스코프를 연결지어서 설명해주세요. |
|
클로저는 함수와 그 함수가 정의된 스코프 간의 관계를 나타내며, 함수가 정의된 스코프의 변수에 대한 참조를 유지합니다. 함수는 외부스코프의 변수에 계속 액세스 하고, 렉시컬 스코프 규칙에 따라 스코프가 결정됩니다. |