logx()의 인수로 x가 들어가지 않았는데도 불구하고 console.log(x)가 실행이 되면서 x가 출력되었다.
<aside> 💡 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에, 자신이 인자로 갖고 있지 않은 변수라도(로컬 변수로 가지고 있지 않은 경우라도) 외부 함수의 지역변수라면 내부 함수에서 사용할 수 있다.
</aside>
let x = 100;
function logx() {
console.log(x);
}
logx();
결과
100
<aside> 💡 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.
</aside>
function makeAdder(x) {
return function(y) {
return x + y;
}
}
const add5 = makeAdder(5); // makeAdder가 선언되고 종료됨
console.log(add5(10)); // 그런데도 makeAdder의 지역변수 x에 접근할 수 있다!
결과
15
위의 예시에서 makeAdder(5);가 실행되고 나서 종료된다. 그럼 이 함수의 지역변수 x에 접근할 수 없는 것이 일반적이다. 하지만 자바스크립트에서는 밑의 결과와 같이 makeAdder의 내부함수 add이 x에 접근하여 결과값을 낼 수 있다.
클로저는 객체의 메소드에서도 사용할 수 있다.
그리고 동일한 외부함수 내에서 만들어진 내부함수나 메소드는 외부 함수의 지역변수를 서로 공유한다. 밑에서 set_title을 통해 title 지역변수를 바꾸면, 그게 get_title 메서드에도 영향을 주어 바뀐 title 값을 사용하는 것을 볼 수 있다.
function factory_movie(title){
return { // 객체 안의 메소드에도 클로저가 적용이 된다.
get_title : function (){
return title;
},
set_title : function(_title){
title = _title
}
}
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');
alert(ghost.get_title()); // 'Ghost in the shell'
alert(matrix.get_title()); // 'Matrix'
ghost.set_title('공각기동대');
alert(ghost.get_title()); // '공각기동대'
alert(matrix.get_title()); // 'Matrix'
이 때 factory_movie의 지역변수 title에 접근할 수 있는 것은 이 함수의 내부 메서드 set_title 뿐이다. 클로저의 이러한 특성을 이용해서 Private한 속성을 사용할 수 있게 된다.
var arr = []
for(var i = 0; i < 5; i++){
arr[i] = function(){
return i;
}
}
for(var index in arr) {
console.log(arr[index]());
}
결과
5 5 5 5 5