JavaScript Closure
업데이트:
클로저
클로저란 간단하게 말하자면 내부함수가 외부함수의 상태를 기억하고 있다 라고 볼 수 있다.
무슨말이냐면 자바스크립트는 싱글스레드로 즉 호출스텍이 하나만 존재한다. 떄문에 한번에 한가지 작업만 가능한데 이러한 특성 때문에 함수는 한번 실행되고나면 호출스텍에서 상태와 함께 사라지게된다. 이렇게되버리면 함수호출 후에 그 내부에서 사용하던 변수나 상태값을에 접근하거나 변경이 불가능해진다. 이떄 사용하는것이 클로저 기법이고 이때 내부함수의 역할이 바로 외부함수의 상태를 기억하고 있어 외부함수가 호출수 사라지더라도 외부함수에서 사용되던 상태나 변수에 접근하여 사용이 가능해진다.
이러하게 사용할 수 있는 이유에는 스코프도 관여한다. 자바스크립트는 렉시컬스코프 방식으로 함수의 상위스코프를 정의하기 떄문에 클로저같은 기법 사용이 가능하다.
렉시컬 스코프
란 함수를 어디서 호출하는지가 아닌 함수가 어디에 선언하였는지에 따라 결정되는 방식이다.
function a () {
console.log(2)
b();
}
function b () {
console.log(1)
}
위와같은경우는 a 함수와 b 함수 둘다 상위스코프는 전역에 존재한다고 볼 수 있다. b 함수는 a 에서 호출되었지만 선언은 전역에 되어있기 때문이다. 클로저를 활용하여 렉시컬스코핑에 따르면 아래와 같이 작성되어야 한다.
function a () {
const x = 1
const b = function () {
console.log(x)
}
return b;
}
a();
이때 내부함수는 외부함수에 존재하던 변수의 복사본에 접근하는것이 아닌 실제 변수에 접근한다는것을 알아야한다.
클로저의 동작방식은 저렇게 간단하게 설명 될 수도있지만 단순히 기억하고있다 라는 말로는 부족할 수 있다. 이 부부에 대한 정확한 이해를 하려면 실행컨텍스트의 동작에 대한 이해가 필요하다.
실행컨텍스트
실행컨텍스트는 실행가능한 코드가 실행되기위한 환경이라고 정의할 수 있다.
자바스크립트에서 실행가능한 코드는 전역코드와 함수내의 코드로 볼 수 있는데 생성된 함수 객체는 [[Scopes]]
라는 프로퍼티는 가지게된다. 이 프로퍼티는 함수객체만이 가지는 내부 프로퍼티로 함수객체가 실행되는 환경을 가르키게된다. 이 프로퍼티는 자신의 실행환경과 자신을 포함하는 외부함수의 실행환경과 전역객체를 가르키게 되는데 이때 자신을 포함한 외부함수가 소멸하여도 [[Scopes]]
프로퍼티가 가르키고 있는 외부함수의 실행환경은 소멸하지않고 참조 할 수 있는데 이것이 정확한 클로저의 실체라고 할 수 있겠다.
실행컨텍스트는 3가지 프로퍼티를 소유하는데 변수객체, 스코프체인, this Value 를 가지게된다. 클로저는 이 스코프체인 프로퍼티 덕분에 가능한 동작이라고 볼 수 있다.
위의 이미지는 클로저의 내부함수를 호출하여 실행컨텍스트를 확인한 예제이다. 클로저로써 실행된 내부 함수의 [[Scopes]]
프로퍼티를 보면 2개의 객제를 찾고있고 그중에 하난 클로저라는 이름으로 외부함수에서 갖고있던 변수인 x 의 값을 그대로 갖고있는걸 확인 할 수 있다. 그밑에 글로벌은 전역실행컨텍스트로 볼 수 있는데 만약 전역에서 선언된 함수였다면 저 글로벌상태만 갖고있게된다.
댓글남기기