RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
앞절에서 이미 언급한 부분입니다. Scope에 관한거죠. 못읽어 보신분이라면 언능가서 먼저 읽으시길 바랍니다. 이 강좌를 하면서 Scope의 개념이 없이는 절대 안되는 부분이거든요. 물론 깊게 설명하지는 않았습니다만,
이번 강좌를 이해하는데 많은 도움이 되리라 생각합니다.

//중첩함수
function A(){
var a = "1";
  function B(){
    var b = "2";
  }
}


이러한 함수가 정의되어 있다고 가정합시다. 함수 A는 a라는 지역변수를 가지고 있고 함수 B는 함수 A안에서
존재하고 b라는 지역변수도 가지고 있습니다.
깜짝 질문, 함수 B에서 a라는 변수를 참조할 수 있을까요? 없을까요? 앞장에서 했던 강좌를 유심히 보신분
이라면 쉽게 알 수 있을 겁니다. 답은 "참조할 수 있다" 입니다. 답은 앞장의 강좌를 다시 읽어서 확인하시기 바랍니다.

참고로 위의 구문은 "중첩함수"라고 부르며 Javascript에서의 private을 만들때 사용하는 방법중에 하나입니다. 실제로 해보시면 아시겠지만, 함수 B는 함수 A안에서밖에 호출할 수 없으며 밖에서 함수 A를 가지고 함수 B를 참조하려 해도 안되는걸 아실 수 있습니다. A.B() <- 이런식으로 절대 호출 할 수 없습니다.

그럼 다음 함수를 보시죠.

<html>
<script>
 function OutFunc(){
   var out = "i'm a out"
   function InFunc(){
     var inner = "i'm a in "+"-----"+ out;
     return inner;
   }
   return InFunc;
 }

 var test_1 = OutFunc();
 var test_2 = test_1();
 alert(test_2);
</script>
<body></body>
</html>

이 스크립트의 결과가 어찌 될거라고 예상이 됩니까? 사실 이 함수 자체를 이해 못하시는 분도 있으리라
생각합니다. 절대 무시하는게 아닙니다. 다만 우리는 알게모르게 쉬운 스크립트만을 접하고 이렇게 구조적으로 파헤친적이 없기때문에 어려울 수 밖에 없었던겁니다. 처음부터 Java 나 C#처럼 배웠다면 이렇게 Javascript가 우리를 힘들게 하지 않았을거라고 전 생각합니다. 일단 실행부터 시켜보세요. 어떻습니까? 여러분이 예상했던 답하고 일치합니까? 일치하다면 자신있게 설명을 하실 수 있습니까? 없다면 아래를 봐주세요 ^^ㅋ

먼저 정리부터 해보죠.
1. Javascript에서의 단위는 함수이다.
2. 함수의 지역변수는 함수밖에서는 절대 호출 할 수 없고, 함수내부에서는 전역변수보다 지역변수가 우선한다.
3. 변수는 각각의 Scope를 가지며 자신의 Scope를 벗어날 수 없다.


이제 소스를 해석해보겠습니다. 다들 청심환 하나씩 드세요. ^^
OutFunc는 자신의 지역변수 out을 가지고 있고 중첩함수인 InFunc를 가지고 있습니다. InFunc는 자신의
지역변수인 inner를 가지고 있고 중첩된 함수(nested function이라고 표현합니다) InFunc는 지역변수 inner를 리턴하는군요. OutFunc는 중첩함수인 InFunc를 리턴하구요. 여기까지 이해하셨죠?

그리고 OutFunc를 실행하고 test_1에 담습니다..여기엔 뭐가 담길까요? 그렇습니다. 함수 InFunc가 담깁니다. 그리고 test_2에는 test_1에 담긴 함수를 실행하고 그결과를 담습니다.

그럼 답을 발표하겠습니다. 답은 "i'm a in -------- i'm a out" 입니다.

제가 묻겠습니다. 변수 inner는 어디에 속해이어야 하는 거죠? 네. 함수 InFunc에 속해서 그 Scope안에서만
존재 해야하며 그함수가 종료되었을때, 같이 사라져야할 변수입니다. 그런데 지금의 모습은 어떻습니까?
alert()을 통해서 inner의 값을 찍고 있습니다. 도대체 어떻게 된 것일까요? 위에 정리한 1,2,3은 도대체
어쩌라고 이렇게 결과가 나오는 겁니까?

눈치가 빠르신분은 이미 알고 계셨을 겁니다. 그렇습니다. 이것이 바로 "클로져(Closure)" 입니다.
클로져의 정의는 "다른 함수내에서 내부객체로 생성된 함수 리터럴을 반환하여 호출 프로그램에서 이를 변수로 배정한 것" 이라고 정의하고 있으며 부연설명으로는 "함수가 동작하는데 필요한 데이터 영역 확장"이라고 하고 있습니다.[o'relly - Javascript for web 2.0 5장]

제가 더 덧붙여 설명하면 첫번째  OutFunc()를 실행함으로써 InFunc()함수를 OutFunc()의 안에서 바깥쪽으로
끄집어내어 영역을 변경(확장)하고 두번째 test_1()을 다시 한번 실행함으로써 inner의 값을 직접 호출 할 수 있도록 호출 프로그램으로 영역을 변경(확장)한 것입니다. 이로써 inner라는 변수는 더이상 OutFunc의
InFunc안에 갇혀있지 않고 어디서든지 호출 될 수 있는 전역변수화가 되어버린 것이죠.
여기까지 이해하셨다면 당신은 이미 중급의 문턱까지 온것입니다.
사실 클로져란것을 정확하게 알고 있는 사람은 드물뿐 아니라 "의도하지 않은 클로져의 생성"으로 고통받고
있는 개발자들도 많습니다. 그만큼 어렵고 이해하기 힘든 개념인 것입니다.

결과적으로만 보면 상당히 훌륭해보이고 멋져 보이지만, 사실 내면엔 "메모리 누수"라는 문제점을 안고
있습니다. 메모리 누수에 대해서는 다음 강좌인 "함수-3"에서 자세히 다뤄보도록 합시다.
오늘은 이만 접어야 겠네요..ㅋ 퇴근시간이 가까워 져서리..ㅋㅋ
그럼 다음 강좌까지 다들 건강조심세요.. 더위가 심하네요..


오늘은 저번 강좌에 이어 클로져에 대해서 이어가겠습니다. 클로져에 대해서 개념이 안잡히신 분들을 위해
간략하게 정리하겠습니다.

함수안에 존재하는 지역변수는 지역변수로써 살아야하며, 함수가 죽으면 따라죽을 운명인데, 클로져는 죽어
마땅한 함수의 지역변수를 밖으로 끄집어내어 영역을 변경(확장)하는 것
을 의미합니다. 물론 이한줄이 클로져를 전부 나타낼 수는 없습니다. 하지만 전 이렇게 설명하려 합니다. 다르게 설명해봤자 서로 헛깔릴게 분명
하거든요 ^^ 사람이든 변수이든 자기의 영역에서 벗어나면 안되나 봅니다..ㅎㅎ 왜냐구요? 클로져도 문제가
좀 심각하거든요... 이름하여 "Memory leak(메모리 누수)" 현상 때문입니다.

메모리 누수의 전체적 그림은 중급강좌정도에 보실 수 있겠네요. 여기서는 클로져에 의한 메모리 누수에
대해서만 다루겠습니다. 메모리 누수 모델이 몇가지 있는데 그걸 다 다루자면 제목에서 보듯이 [기초강좌]에서 범위가 벗어납니다. 우리가 좀전에 뭘 배웠습니까? 영역을 벗어나면 문제가 된다고 했지요 ㅎㅎㅎㅎ

자 다시 본론으로 가서, 클로져는 한 내부함수의 지역변수를 함수 리터럴을 통하여 밖으로 꺼내오는 것을
의미한다 했습니다. 그럼 제가 질문을 해보겠습니다. 그 한 내부함수가 종료되면 클로져에 의해 밖으로
튀어나온 변수는 어떻게 될까요? 그렇습니다... 계속 살아 있습니다. 계속 살아있으므로 부모함수가 죽었는데도 불구하고 계속 호출되어 사용됩니다. 나중에 다시 이야기 되겠지만 이것이 "IE에서의 메모리 누수 모델 1"
입니다. 보통 FireFox나 오페라 같은 브라우저는 클로져가 생성되어도 참조값이 0이면 브라우저메모리에서
GC에의해 소멸되게 됩니다. 허나, IE는 그렇지 못하여 문제가 되는거죠. 전 강좌를 열심히 보신분이라면 쉽게 이해하시리라 봅니다. 클로저의 메모리 누수는 이쯤으로 마치겠습니다. 사실 메모리 누수에 대해서는 할말이
무지 많습니다. 허나, 역시 범위를 넘기면 문제가 ㅎㅎㅎㅎ



posted by blankus

--------------------- 펌글 ---------------------


음냥 초보자들이 알기 딱좋네 !!

나두 넘 좋아 나도 초보거등 ~~~ ㅋㅋㅋ
2007/11/21 12:54 2007/11/21 12:54
이 글에는 트랙백을 보낼 수 없습니다
웅쓰:웅자의 상상플러스
웅자의 상상플러스
전체 (379)
게임 (5)
영화 (2)
기타 (23)
맛집 (5)
영어 (2)
대수학 (3)
형태소 (5)
Hacking (9)
Linux (112)
HTML (48)
Application_developing (48)
Web_developing (102)
Window (11)
«   2024/12   »
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 26 27 28
29 30 31        
  1. 2016/01 (1)
  2. 2015/12 (3)
  3. 2015/10 (3)
  4. 2015/03 (2)
  5. 2015/01 (4)