프로그래밍/

자바스크립트의 1급객체와 클로저 개념

Jay22 2017. 2. 1. 15:30
반응형


javascript의 매우 헷갈리는 부분에 대해서 보자.



1
2
3
4
5
6
7
8
9
10
11
function outer() {
    var count = 0;
    var inner = function() {
      return ++count;  
    };
    return inner;
}
var increase = outer();
 
console.log(increase());
console.log(increase());
cs


자 이 함수롤 보자.


콘솔에 찍히는 것으로 구분을 해보면서 볼건데 결과값은 1,2가 나온다.

외부함수를 실행하고 외부함수안에서 내부함수(inner)를 실행하지 않고 반환한다. return inner;

그리고 외부변수 increase에 담아서 저장한다. 실행은 increse()로 해줘야 1,2 가 나온다. 

왜그럴까?


count변수는 outer안에 지역적으로 선언이 되었지만 inner내부함수안에서 스코프 규칙에 의해 접근이 가능하다. 하지만 글로벌쪽에서는 inner함수만 호출이 되므로 count가 계속 올라가는 것이다.


여기서 그냥 console.log(increase)하면 어떻게 될까?


리턴값으로 1,2 가 아닌 function() { return ++count; } 함수(콘솔상에선 문자열처럼 표기됨)가 튀어나오게 된다. 즉 increase는 변수인데 함수를 집어넣어놨고 실행하지 않고 출력을 시켰으므로 함수 자체가 나오게 된다.



자 그럼 위의 코드를 약간 변형해 보자.


1
2
3
4
5
6
7
8
9
10
11
function outer() {
    var count = 0;
    var inner = function() {
      return ++count;  
    };
    return inner();
}
var increase = outer();
 
console.log(increase);
console.log(increase);
cs


outer함수안에서 내부함수를 호출하면서 넘겼다. 그 결과값을 increase변수에 담았다. 그러면 1이 저장되는 것이 자명하다. 다시 콘솔로 호출해봐도 똑같은 결과가 나온다. 왜냐하면 inner() 로 리턴하게 되면 결과값 즉 count에서 1이 증가되어 1의 값으로 변경된 것을 리턴하게 되는 것이다. 즉 계산이 완료되어 리턴을 하게된다. 글로벌쪽에서는 count를 컨트롤 할 수가 없게 된다.

즉 1,1이 출력된다. 


그렇다면 콘솔에 increase()로 호출하면 어떻게 될까? 


당연히 오류다. 이미 호출해서 반환받은것을 또 호출하려고하니 함수가 아니라는 에러가 뜰 것이다. 



결론 자바스크립트 객체는 1급 객체(First Class Object)이다.


파라미터로 전달될 수 있고 리턴 값으로 사용될 수 있고 변수에 할당될 수 있고 런타임에 생성될 수 있다는 뜻이다. 매우 flexible하지 않은가?






반응형