이글은 MDN을 바탕으로 작성된 글입니다.
[https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures]
클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. "범위 밖에서도 범위 안의 인자에 접근할수 있는 것."
클로저는 어떤 데이터(어휘적환경)와 그 데이터를 조작하는 함수를 연관시켜주키때문에 유용하다. _MDN
클로저는 내부함수가 외부함수의 맥락에 접근할 수 있는 것을 가리킨다.
클로저는 내부함수와 밀접한 관계를 가지고 있는 주제다. 내부 함수는 외부함수의 지역변수에 접근할 수 있는데 외부 함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근할 수 있다. 이러한 메커니즘을 클로저라고 한다.
_생활코딩
클로저란 내부함수가 외부함수의 지역변수에 접근할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될때까지 소멸되지 않는 특성을 의미한다. _생활코딩
[예제 1]
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수
function displayName() { //displayName() 은 내부 함수이며, 클로저다.
alert(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
위 예제에서 init() 메서드안에 정의 되어 있는 displayName() 메서드가 바로 클로저다.
함수안에 정의된 새로운 함수를 '클로저'라고 생각하면 된다.
[예제 2]
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
// myFunc 변수에 displayName을 리턴함
// 유효 범위의 어휘적 환경을 유지.
myFunc();
// 리턴된 displayName 함수를 실행(name 변수에 접근)
예제 1과 별반 다르지 않다. 다른점은
var myFunc = makeFunc();
myFunc();
이 부분이다.
함수의 리턴값을 변수에 저장한뒤 그 변수를 함수처럼 이용한다.
예제 2의 makeFunc() 메서드는 자바에서의 '클래스'와 아주 유사하게 느껴진다.
[예제 3]
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)
!! 부분을 보면 makeAdder() 메서드가 자바의 클래스처럼 쓰인 것을 볼 수 있다.
하나의 메서드(makeAdder)로 'add5'와 'add10' 두개의 다른 기능을 가진 변수를 만들었고.
그 변수를 이용할수 있게 되었다. '다형성'을 지녔다고 할수 있다.
본질적으로 makeAdder는 함수를 만들어내는 공장이다. 이는 makeAdder함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴한다는 것을 의미한다. 위의 예제에서 add5, add10 두 개의 새로운 함수들을 만들기 위해 makeAdder함수 공장을 사용했다. 하나는 매개변수 x에 5를 더하고 다른 하나는 매개변수 x에 10을 더한다.
add5와 add10은 둘 다 클로저이다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다. 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5 이지만 add10의 맥락적 환경에서 x는 10이다. 또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.
[예제 4] private method 흉내내기
var counter = (function() { // 클래스와 비슷하다고 생각하고
var privateCounter = 0; // private 변수로 생각하면 똑같이 기능한다.
function changeBy(val) {
privateCounter += val;
}
return {
incrememt: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
console.log(counter.value()); // logs 0
counter.incrememt();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1
counter를 Class라고 생각하고 "var privateCounter" 를 private 변수라고 생각하면 이해가 될 것이다.
똑같이 작동한다.
클로저의 정의를 다시 읽고 마무리.
클로저는 어떤 데이터(어휘적환경)와 그 데이터를 조작하는 함수를 연관시켜주키때문에 유용하다. _MDN
클로저는 내부함수가 외부함수의 맥락에 접근할 수 있는 것을 가리킨다.
클로저는 내부함수와 밀접한 관계를 가지고 있는 주제다. 내부 함수는 외부함수의 지역변수에 접근할 수 있는데 외부 함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근할 수 있다. 이러한 메커니즘을 클로저라고 한다.
_생활코딩
클로저란 내부함수가 외부함수의 지역변수에 접근할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될때까지 소멸되지 않는 특성을 의미한다. _생활코딩
'JavaScript' 카테고리의 다른 글
node / express 공부기. (0) | 2020.04.25 |
---|---|
JS 배열 정리하고 가기. (0) | 2020.04.24 |
JS 문자열 메서드 훑고 가기. (0) | 2020.04.24 |
You Don't Know Node / translate (0) | 2020.04.22 |
var / let / const 간단정리 (0) | 2020.04.22 |