본문 바로가기

JavaScript

closure

이글은 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