- Published on
클로저의 개념
- Authors
- Name
- piano cat
클로저는 내부 함수가 외부 함수의 맥락에 접근할 수 있는 것을 의미합니다.
이를 통해 자바스크립트는 private 변수를 구현할 수 있어, 이는 다른 많은 프로그래밍 언어에서 중요한 객체 지향 프로그래밍 개념입니다.
클로저의 간단한 예시로는 다음과 같습니다.
예시1
function outerFunction(outerVariable) {
function insideFunction(innerVariable) {
console.log('outerVariable:', outerVariable)
console.log('innerVariable:', innerVariable)
}
return insideFunction
}
const newFunction = outerFunction('outside')
newFunction('inside')
// logs: outerVariable: outside, innerVariable: inside
위의 코드에서 outerFunction
은 innerFunction
을 반환하고, innerFunction
은 outerVariable
에 접근하는 클로저입니다. 이렇게 클로저를 사용하면, 함수의 실행 후에도 변수에 접근할 수 있어 데이터를 은닉하거나 캡슐화하는 등의 활용이 가능합니다.
또한 클로저는 비동기 처리나 이벤트 핸들러, 콜백 함수 등에서도 유용하게 활용됩니다.
가능한 이유?
이러한 방법이 가능한 이유는 무엇일까?
예시2
// 외부 함수인 outer를 선언
function outer() {
let count = 0
function inner() {
count++
return count
}
return inner
}
const counter = outer()
console.log(counter()) // 1 (count가 0에서 1로 증가)
console.log(counter()) // 2 (count가 1에서 2로 증가)
예시2를 보면, 아래 counter 라는 변수에 outer 함수를 할당했다. outer함수는 inner함수를 반환하기때문에
counter 변수는 inner함수가 될것이다.
하지만 inner 함수의 외부에 있는 함수의 스코프에 어떻게 접근할수 있고 변화되는 상태값을 계속 가지고 있을수 있을까
이유는 반환된 inner 함수가 클로저를 형성하기 때문에 접근이 가능한 것이다. 클로저는 반환된 Inner 함수가 자신이 선언되었을때의 환경(렉시컬 환경)에서의 스코프를 기억하기 때문이다. 즉, couter 변수에 할당한 반환된 Inner 함수는 count 라는 변수를 기억할수 있다.
비동기 함수에 활용된 클로저
function asyncGreeting(delay, name) {
setTimeout(() => {
console.log('Hello, ' + name)
}, delay)
}
asyncGreeting(1000, 'John Doe') // 1초 후에 "Hello, John Doe"를 출력합니다.
여기서 setTimeout
함수는 비동기 함수로, 지정된 시간이 지난 후에 콜백 함수를 실행합니다. 이 때, 콜백 함수는 asyncGreeting
함수의 매개변수 name
에 접근하고 있습니다. 이렇게 비동기 함수의 콜백에서 외부 함수의 변수를 사용할 수 있는 것이 바로 클로저의 활용입니다.
이벤트 핸들러에 활용된 클로저
var elements = document.getElementsByTagName('button')
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener(
'click',
(function (i) {
return function () {
console.log('You clicked element #' + i)
}
})(i)
)
}
위의 코드는 페이지 내의 모든 버튼에 클릭 이벤트 핸들러를 추가하는 예시입니다. 각 이벤트 핸들러는 클로저를 통해 자신이 몇 번째로 생성된 핸들러인지를 i
변수에서 가져옵니다. 이렇게 클로저를 통해 각 핸들러가 자신의 인덱스를 기억하도록 할 수 있습니다.
위의 예시들처럼 클로저는 함수의 지역 변수가 사라지더라도 그 변수에 접근할 수 있도록 해주므로, 비동기 처리나 이벤트 핸들러 등에서 유용하게 활용됩니다.