나는 프렌즈를 정말 좋아한다.
봐도봐도 질리지 않는 에피소드들의 연속 그리고 특히 제일 좋아하는 에피소드 중 하나에 클로져에 대한 이야기도 나온다.
물론 여기서 다룰 클로져와는 다른 뜻을 가지지만...
여튼 이렇게 프렌즈와의 인연을 만들어보며 클로져에 대해 이야기를 시작해보겠다.
JS에서 모든 변수나 파라미터들은 선언된 위치의 scope 밖에서는 사용할 수 없다. 하지만 밖에서 선언된 변수는 안에서 사용될 수 있다.
scope : 변수에 접근할 수 있는 범위
가령 함수 안에 있는 함수에서는 밖에있는 함수의 변수나 전역변수들을 사용할 수 있다. 하지만 밖에 있는 함수에서는 안에있는 함수에서의 변수를 쓸 수 없다.
---> 렉시컬 환경이 다르다.
JS환경 내 모든 함수는 클로져의 특징을 가지고 있다.
만약 어떤 함수가 외부 scope의 변수를 참조한다면 그 외부의 변수는 사용될지도 모르기 때문에 함수 내에 기억된다.
그리고 마침내 함수가 실행될 때 해당 변수의 가장 최신값을 가져온다.
let userName = 'max'
function sayHi(){
console.log('HI' + userName)
}
userName = 'kang'
sayHi()
콘솔 창에는 무엇이 출력될까? HI max 일까? HI kang 일까?
코드가 작성된 시점에 userName은 max이다. 하지만 함수가 실행되는 시점에 userName은 kang이다 따라서 답은
HI kang 이다
함수가 실행되는 시점에 가장 가까운(close) 값을 가지게 된다는 특징이 closure다.
function sayHello(name){
let text = "Hello" + name;
return function(){
console.log(text)
}
}
let sayAsim = sayHello('Asim")
sayAsim()
이 경우는 어떨까?
sayAsim을 실행하면 그안에 쓰인 변수는 사용되고 바로 삭제된다.
즉 return 된 함수에 text는 값이 없어야 한다.
하지만 closure라는 특성 때문에 이 값을 계속 기억하고 sayAsim()은 Hello Asim 을 출력한다.
클로져는 JS 개발자가 자주 헷갈리는 개념중에 하나라고 생각한다. 이거랑 this는 솔직히 아직도 헷갈린다.
하지만 앞서 다루었던 EC의 과정을 잘 이해하면 클로저와 this 그리고 hoisting을 잘 이해할 수 있으리라 생각된다.
참고
Udemy Advanced Javascript - Asim Hussain