클로저
함수가 선언된 환경의 조합
클로저를 이해하려면 변수의 유호범위(lexical scoping)을 먼저 이해해야 함
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
//myFunc변수에 displayName을 리턴함
//유효범위의 어휘적 환경을 유지
myFunc();
//리턴된 displayName 함수를 실행(name 변수에 접근)
displayName()함수가 실행되기 전에
외부함수인 makeFunc()로부터 리턴되어 myFunc 변수에 저장된다
몇몇 프로그래밍 언어에서, 함수 안의 지역 변수들은 그 함수가 처리되는 동안에만 존재한다
makeFunc() 실행이 끝나면(displayName함수가 리턴되고 나면)
name 변수에 더 이상 접근할 수 없게 될 것으로 예상하는 것이 일반적이다
하지만 위의 예시와 자바스크립트의 경우는 다르다
그 이유는 자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문이다
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다
이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다
myFunc은 makeFunc이 실행 될 때 생성된 displayName 함수의 인스턴스에 대한 참조다
displayName의 인스턴스는 변수 name 이 있는 어휘적 환경에 대한 참조를 유지한다
이런 이유로 myFunc가 호출될 때 변수 name은 사용할 수 있는 상태로 남게 되고 "Mozilla" 가 alert 에 전달된다
function makeAdder(x) {
var y = 1;
return function(z) {
y = 100;
return x + y + z;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
//클로저에 x와 y의 환경이 저장됨
console.log(add5(2)); // 107 (x:5 + y:100 + z:2)
console.log(add10(2)); // 112 (x:10 + y:100 + z:2)
//함수 실행 시 클로저에 저장된 x, y값에 접근하여 값을 계산
단일 인자 x를 받아서 새 함수를 반환하는 함수 makeAdder(x)를 정의했다
반환되는 함수는 단일인자 z를 받아서 x와 y와 z의 합을 반환한다.
본질적으로 makeAdder는 함수를 만들어내는 공장이다
이는 makeAdder함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴한다는 것을 의미한다
위의 예제에서 add5, add10 두 개의 새로운 함수들을 만들기 위해 makeAdder함수 공장을 사용했다
하나는 매개변수 x에 5를 더하고 다른 하나는 매개변수 x에 10을 더한다
add5와 add10은 둘 다 클로저이다
이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다
함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5 이지만 add10의 맥락적 환경에서 x는 10이다
또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다 (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며
클로저에 단순히 값 형태로 전달되는것이 아니라는 것을 의미한다
참조: https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
'프로그래밍 언어 > JS' 카테고리의 다른 글
JavaScript) 함수의 합성(function composition) (0) | 2022.03.22 |
---|---|
JavaScript) 함수형과 절차형 프로그래밍 (0) | 2022.03.22 |
JavaScript) 커링(currying)과 렉시컬 환경 (0) | 2022.03.16 |
JavaScript) MapReduce Model (0) | 2022.03.16 |
JavaScript) 내장 배열 고차함수 (0) | 2022.03.15 |
댓글