정의
- 클로저는 함수와 함수가 선언된 어휘적 환경의 조합.
- 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야.
어휘적 범위 지정(Lexical scoping)
function init() {
var name = 'Mozilla';
function printName() {
console.log(name);
}
printName();
}
init();
- 위 코드를 실행하면 printName() 함수 내의 console.log()문이 부모 함수에서 정의한 변수 name의 값을 성공적으로 출력함.
- 이 예시를 통해 함수가 중첩된 상황에서 파서가 어떻게 변수를 처리하는지 알 수 있다.
이는 어휘적 범위 지정(lexical scoping)의 한 예다.
- lexical ?
어휘적 범위 지정(lexical scoping) 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미
- 중첩된 함수는 외부 범위(scope)에서 선언한 변수에도 접근할 수 있다.
클로저(Closure)
예시 1
function makeFunc() {
var name = 'Mozilla';
function printName() {
console.log(name);
}
return printName;
}
var myFunc = makeFunc();
myFunc();
- 몇몇 프로그래밍 언어에서, 함수 안의 지역 변수들은 그 함수가 처리되는 동안에만 존재.
makeFunc() 실행이 끝나면 (printName 리턴되고 나면)
name 변수에 더 이상 접근할 수 없게 될 것으로 예상하는 것이 일반적.
- 자바스크립트의 경우엔 다름.
- 자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문.
- 클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
- 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.
예시 2
function makeAdder(x) {
var y = 1;
return function (z) {
y = 100;
return x + y + z;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2));
console.log(add10(2));
- add5와 add10은 둘 다 클로저.
- 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다.
- 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5 이지만 add10의 맥락적 환경에서 x는 10이다.
또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (x값도 동일하게 변경 가능하다.)
- 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며
클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미.
이게 맞는 걸까? 혼자 짜보는 코드
- 이 로직은 어떻게 돌아가는 걸까? (화살표 함수를 이용해서 한번 만들어봄)
const testFunc = (x) => (y) => (z) => x + y + z;
let testX = testFunc(1);
console.log('testX: ', testX);
let testY = testX(2);
console.log('testY: ', testY);
let testZ = testY(3);
console.log('testZ: ', testZ);
참고 자료
정의
어휘적 범위 지정(Lexical scoping)
이는 어휘적 범위 지정(lexical scoping)의 한 예다.
어휘적 범위 지정(lexical scoping) 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미
클로저(Closure)
예시 1
makeFunc() 실행이 끝나면 (printName 리턴되고 나면)
name 변수에 더 이상 접근할 수 없게 될 것으로 예상하는 것이 일반적.
예시 2
또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (x값도 동일하게 변경 가능하다.)
클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미.
이게 맞는 걸까? 혼자 짜보는 코드
참고 자료