클로저(closure)는 지역변수를 (내부함수(inner function)안에 있는 변수) 전역변수(외부함수(outter function)처럼
살아있게끔 만들어줍니다.
내부함수가 외부함수의 맥락에 접근이 가능한것을 말하는것이죠. (Hoisting)
1
2
3
4
5
6
7
8
|
function outter() {
var local = 'local'; // 외부함수에 변수를 선언합니다.
function inner() { // inner()는 외부함수 안에 선언된 내부함수입니다.
alert(name); // 외부함수에서 선언된 변수를 내부함수에서 호출합니다.
}
inner();
}
outter();
|
See the Pen GRgvJmJ by LeeSiHwang (@leesihwang) on CodePen.
(Run Pen 클릭 시 alert가 실행됩니다)
외부함수 내에서 내부함수가 선언되고 호출이 되었습니다.
이것을 실행이 되는 관점으로 보자면
1. 내부함수 안에서 변수 local
을 찾는다. ( scope )
2. 자신의 함수안에서 변수 local
을 찾지 못하여 외부함수의 스코프에서 변수 local을 찾는다.
3. 변수 local
을 찾았다 ( 내부함수가 외부함수의 변수에 접근하였다 )
위에서 말씀드렸듯이 내부함수가 외부함수의 맥락에 접근이 가능한것 입니다.
2. 클로저(closure)의 활용
내부함수는 외부함수의 지역변수를 참조할 수 있는데 외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근 할 수 있습니다. 이런것을 클로저라고 합니다..
클로저가 유용하게 사용되는 경우는 다음 예제와 같이 변경된 상태를 유지/기억 하는 것입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function outterFn(){
var inner = 0;
var innerFn;
innerFn = function(){
console.log(inner++);
}
return innerFn;
}
var nestFn = outterFn();
nestFn(); // 0
nestFn(); // 1
nestFn(); // 2
nestFn(); // 3
nestFn(); // 4
|
1. outterFn 함수는 실행되고 innerFn을 반환하고 사라졌습니다.
2. innerFn 즉 내부함수는 자신이 찾았던 변수inner
를 기억하는 클로저입니다.
3. 내부함수는 자신이 찾았던 변수inner를 필요로하며, 내부함수가 기억하는 Lexical환경의 변수inner
는 사라지지 않고, 현 상태를 기억합니다.
4. 외부함수를 호출하면, 변수inner
의 값이 변경됩니다.
변수 inner
는 클로저에의해 참조되고 있기 때문에 사라지지않고 계속 유지되며, 자신이 변경된 상태를 계속해서 유지합니다.
2. 클로저(closure)의 은닉화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<p>사과 1박스</p>
<p id="count">0</p>
<button id="plusNum">증가</button>
<button id="minusNum">감소</button>
<script>
var privateNum = 0;
function plus(){
privateNum++;
document.getElementById("count").innerText = privateNum;
}
function minus(){
privateNum--;
if(privateNum <= 0){
privateNum = 0;
}
document.getElementById("count").innerText = privateNum;
}
document.getElementById("plusNum").addEventListener("click",function(){
plus();
});
document.getElementById("minusNum").addEventListener("click",function(){
minus();
});
</script>
|
See the Pen RwNZPqr by LeeSiHwang (@leesihwang) on CodePen.
이렇게 코드를 작성한다해도 별문제없이 작동합니다.
하지만 이 코드는 addEventListener가 작동하기 이전에 count의 값이 반듯이 0이여야합니다.
변수 privateNum
은 전역변수이기 때문에 언제든지 누구나 접근,변경이 쉽습니다.
변수 privateNum
의 의도치않은 변경은 오류를 불러올 수 있기 때문에, 이 privateNum은
함수가 관리하는것이 좋습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<p>사과 1박스</p>
<p id="count">0</p>
<button id="plusNum">증가</button>
<button id="minusNum">감소</button>
<script>
var plusMinus = (function(){
var privateNum = 0;
return{
plus : function(){
privateNum++;
document.getElementById("count").innerText = privateNum;
},
minus : function(){
privateNum--;
if( privateNum <= 0 ){
privateNum = 0;
}
document.getElementById("count").innerText = privateNum;
}
}
})();
</script>
|
See the Pen https://codepen.io/leesihwang/pen/gObxpyL">
gObxpyL by LeeSiHwang (https://codepen.io/leesihwang">@leesihwang)
on https://codepen.io">CodePen.
이렇게 해결이 가능합니다.
그럼 만약에 단순히 변수 privateNum
을 지역변수로 클로저 없이 사용한다면 어떻게 될까요?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<p>사과 1박스</p>
<p id="count">0</p>
<button id="plusNum">증가</button>
<button id="minusNum">감소</button>
<script>
function plus(){
var privateNum = 0;
privateNum++;
return document.getElementById("count").innerText = privateNum;
}
function minus(){
var privateNum = 0;
privateNum--;
return document.getElementById("count").innerText = privateNum;
}
document.getElementById("plusNum").addEventListener("click",function(){
plus();
});
document.getElementById("minusNum").addEventListener("click",function(){
minus();
});
</script>
|
이렇게 코드를 작성하고 실행해봅니다.
See the Pen https://codepen.io/leesihwang/pen/dyPzoxo">
dyPzoxo by LeeSiHwang (https://codepen.io/leesihwang">@leesihwang)
on https://codepen.io">CodePen.
변수 privateNum이 plus함수와 minus함수와 서로 다른 변수 privateNum
으로 인식이되어 따로놀고있으며,
함수 실행 후, 클로저가 없기때문에 변수 privateNum
이 유지되거나 기억되지못해
plus버튼의 경우 0에서 1로만, minus버튼의 경우 0에서 -1로만 값이 유지되는것을 확인할 수 있습니다.
'Language' 카테고리의 다른 글
[Java] 자바를 이용한 구구단 게임 만들기 (0) | 2020.08.27 |
---|---|
알아두면 좋은 CSS 선택자 (0) | 2020.08.27 |
[CSS] CSS 기초설명, Cascading 이란? (0) | 2020.08.27 |
[HTML] HTML 기초설명 (0) | 2020.08.27 |
[자바스크립트]Virtual Dom이란? (0) | 2020.08.27 |