클로저(Closure)란?
클로저는 외부 함수의 변수에 접근할 수 있는 내부 함수 또는, 이러한 작동 원리를 일컫는 용어이다. 클로저 함수 안에서는 지역 변수(Local Variable), 외부 함수의 변수(Outer Function Variable), 전역 변수(Global Variable)의 접근이 전부 가능하다. 그렇기 때문에 클로저는 일반적으로 사이드 이펙트를 제어할 때와 private 변수를 생성할 때 많이 사용된다고 한다.
function outerFn() {
let outerVar = 'outer';
console.log(outerVar);
function innerFn() { // -> 클로저 함수
let innerVar = 'inner';
console.log(innerVar);
}
return innerFn;
}
outerFn()(); // 외부 함수와 내부 함수를 연달아 호출함.
// -> outer inner
let innerFn = outerFn(); // 외부 함수의 리턴값을 innerFn이라는 변수에 담음.
// -> outer
innerFn(); // 내부 함수가 담긴 innerFn을 호출함.
// -> inner
유용한 클로저 예제
커링: 함수 하나가 n개의 인자를 받는 대신, n개의 함수를 만들어 각각 인자를 받게 하는 방법
function adder (x) {
return function (y) {
return x + y;
}
}
adder(2)(3); // 5
let add100 = adder(100);
add100(2); // 102
add100(10); // 110
let add5 = adder(5);
add5(2); // 7
위에 예제처럼 클로저를 사용하면 x의 값을 고정해놓고 재사용할 수 있다.
function htmlMaker(tag) {
let startTag = '<' + tag + '>';
let endTag = '</' + tag + '>';
return function (content) {
return startTag + content + endTag;
}
}
let divMaker = htmlMaker('div');
divMaker('code'); // <div>code</code>
divMaker('states'); // <div>states</div>
let h1Maker = htmlMaker('h1');
h1Maker('Headline'); // <h1>Headline</h1>
외부 함수의 변수가 저장되어 마치 템플릿 함수와 같이 사용 가능하기에 위같은 기능을 하는 함수도 만들 수 있다.
클로저 모듈 패턴: 변수를 스코프 안쪽에 가두어 함수 밖으로 노출 시키지 않는 방법
function makeCounter() {
let privateCounter = 0;
return {
increment: function() {
privateCounter++;
},
decrement: function() {
privateCounter--;
},
getValue: function() {
return privateCounter;
}
}
}
let counter1 = makeCounter();
counter1.increment();
counter1.increment();
counter1.getValue(); // 2
let counter2 = makeCounter();
counter2.increment();
counter2.decrement();
counter2.increment();
counter2.getValue(); // 1
두 카운터에 각기 다른 privateCounter를 다루면서, privateCounter를 밖으로 노출시키지 않는다. 이와 같이 클로저는 데이터를 숨기고 정해진 방법을 통해서만 데이터를 접근할 수 있도록 제한을 두는 데 활용되기도 한다.
function makeFib() {
var arr = [0,1]
return function() {
var num = arr[arr.length - 2]
var len = arr.length;
arr.push(arr[len - 1] + arr[len - 2]);
return num;
}
}
var fn = makeFib()
fn(); // 0
fn(): // 1
fn(): // 1
fn(): // 2
fn(): // 3
fn(): // 5
함수를 호출할 때마다 0부터 시작해 피보나치 수열을 출력하는 함수이다. 안쪽 스코프에서 만들어진 함수에서 바깥 스코프의 변수(arr)를 사용하고 있다. 이 함수를 통해 바깥 스코프에 해당하는 코드의 실행이 끝나더라도 계속 변수를 사용할 수 있다.
'Programming' 카테고리의 다른 글
[JavaScript] 객체지향 프로그래밍 - ES6 class 키워드없이 구현하기 (2) | 2020.07.29 |
---|---|
[JavaScript] Data Structure - Stack, Queue (0) | 2020.07.28 |
[JavaScript] this, call, apply, bind (0) | 2020.07.22 |
[JavaScript] 스코프 - 함수/변수를 선언할 때 주의해야 되는 4가지 (0) | 2020.07.20 |
[JavaScript] Array Method 정리 (0) | 2020.07.18 |