자바스크립트 함수 유효범위(Scope) 관리 및 Closer



1. 함수 생성시


함수 객체의 [[Scope]] 속성 :
 
다른 객체와 마찬 가지로 함수 객체 또한 자신만의 속성을 가지고 있습니다.


하지만 여기서 속성은 코드에서 접근할수있는 속성과 그렇지 않은 속성
2가지로 나뉩니다.


[[Scode]] 속성은 "자바스크립트" 엔진 에서만 접근 가능한 속성이며, 해당 함수 객체의 
Scode Chain을 포함 
하는 속성 이기도 합니다.







1. 함수 객체 생성시 [[Scope]] 속성이 만들어지며 
자신만의 식별자 검색을
위한
Scope chain을 포함 합니다.


2. Scope Chain 에 전역객체(Global object)추가 됩니다.

3. 전역 객체(Global object)는 함수에서 접근 할 수 있는 전역 변수 와 함수 전체를
담은
객체이며 이 객체는 this, window, document, function 을 포함 합니다.



위 그림을 코드로 표현하면 아래와 같습니다.


  1. function fnScope(num1, num2){
  2.    
  3.     var sum = num1 + num2;
  4.  
  5.     return sum;
  6. }



2. 함수실행시


Execution Context (실행 문맥) : 
함수가 실행되는 환경을 정의 합니다.


여기서 실행환경이란?


함수가 접근 할 수 있는 데이터 목록과 그 데이터를 가져오거나 설정하기 위한 환경 입니다.





1. 함수 실행시 "실행 컨텍스트" 객체가 생성됩니다.


2. 실행 컨텍스트도 자신만의 식별자 검색을 위한 "Scope chain"을 포함 합니다.

3. "Scope Chain"은 함수의 [[Scope]] 속성에 있는 전역 객체(Global object)로
초기화
됩니다.


4. 초기화 과정이 끝나면 Activation object(활성화 객체) "Scope Chain" 에 추가
됩니다.


5. Activation object 는 "this", "Aguments 집합", "지역변수",
"매개변수" 항목을
포함 합니다.


6. Activation object 생명 주기는 함수가 종료 될 때 같이 소멸 됩니다.



위 그림을 코드로 표현하면 아래와 같습니다.



  1. function fnScope(num1, num2){
  2.    
  3.     var sum = num1 + num2;
  4.  
  5.     return sum;
  6. }
  7.  
  8. fnScope(5, 10); //함수 실행




3. Scope Chain 의 확장 [ with문 ]


함수 실행시 with문을 만나면 해당 객체의(with문에 선언된 객체)속성 전체를 포함 하는
변수 객체를 Scope chain에 임시적으로 추가 확장 합니다.





1. 함수 실행시 "실행 컨텍스트" 객체가 생성됩니다.

2. 실행 컨텍스트도 자신만의 식별자 검색을 위한 "Scope chain"을 포함 합니다.

3. "Scope Chain"은 함수의 [[Scope]] 속성에 있는 전역 객체(Global object)로 
초기화
 됩니다.


4. 초기화 과정이 끝나면 Activation object(활성화 객체) "Scope Chain" 에 추가 
됩니다.


5. Activation object 는 "this", "Aguments 집합", "지역변수", 
"매개변수" 항목을 
포함 합니다.
 

6. with문을 만나면 해당 객체(with문에 선언된 객체)의 속성 전체를 포함하는 변수 객체를
Scope chain에 임시 적으로 추가확장 합니다.

7. Activation object 생명 주기는 함수가 종료될때 같이 소멸됩니다.




위 그림을 코드로 표현 하면 아래와 같습니다.



  1. //with object 생성
  2. var with_object = {
  3.    
  4.     name: 'with_object',
  5.     getName: function(){
  6.         return 'name';
  7.     }
  8. }
  9.  
  10. function fnScope(num1, num2){
  11.    
  12.     var sum = num1 + num2;
  13.  
  14.     with (with_object)
  15.     {
  16.         alert(name); // with_object
  17.         alert(getName()); // name
  18.     }
  19.  
  20.     return sum;
  21. }
  22.  
  23. fnScope(5, 10); // 함수 실행



4. Scope Chain 확장 [ catch문 ]

함수 실행시 try 블록에서 에러가 발생하면 실행 흐름은 catch문으로 넘어가고,
catch블록 안의지역변수 전체Scope chain에 임시 적으로 추가 확장됩니다.






1. 함수 실행시 "실행 컨텍스트" 객체가 생성됩니다.

2. 실행 컨텍스트도 자신만의 식별자 검색을 위한 "Scope chain"을 포함 합니다.

3. "Scope Chain"은 함수의 [[Scope]] 속성에 있는 전역 객체(Global object)로 
초기화
 됩니다.


4. 초기화 과정이 끝나면 Activation object(활성화 객체) "Scope Chain" 에 추가 
됩니다.


5. Activation object 는 "this", "Aguments 집합", "지역변수", 
"매개변수" 항목을 
포함 합니다.
  

6. try 블록에서 에러가 발생하면 실행 흐름은 catch문으로 넘어가고 catch 블록 안의
지역변수 전체가 Scope chain에 임시 적으로 추가 확장 합니다.

7. Activation object 생명주기는 함수가 종료될때 같이 소멸됩니다.





위 그림을 코드로 표현하면 아래와 같습니다.

  1. function fnScope(num1, num2){
  2.    
  3.     var sum = num1 + num2;
  4.  
  5.     try{
  6.     }
  7.     catch(e){
  8.         var msg = 'msg'; //스코프 확장
  9.         alert(e.message);
  10.     }
  11.  
  12.     return sum;
  13. }
  14.  
  15. fnScope(5, 10); // 함수 실행





5.
closer 생성


closer : 함수가 자신의 스코프 밖에 있는 데이터에 접근하려는 행위.





1. 함수 실행시 "실행 컨텍스트" 객체가 생성됩니다.

2. 실행 컨텍스트도 자신만의 식별자 검색을 위한 "Scope chain"을 포함 합니다.

3. "Scope Chain"은 함수의 [[Scope]] 속성에 있는 전역 객체(Global object)로 
초기화
 됩니다.


4. 초기화 과정이 끝나면 Activation object(활성화 객체) "Scope Chain" 에 추가 
됩니다.


5. Activation object 는 "this", "Aguments 집합", "지역변수", 
"매개변수" 항목을 
포함 합니다.
   

6. scopeFunction() 함수 생성 closer가 발생 합니다.

" closer 가 발생 하는 이유는? 설명 에서와 같이 scopeFunction 함수가 자신의 유효범위
밖에 있는
함수의 지역변수에 접근하기 때문입니다."


7. closer 생성시 closer의 [[Scope]] 속성은 fnScope의 실행 컨텍스트 객체(Activation object, global object)로 초기화 됩니다.

8.  closer 의 Scope Chain 에 포함된  Activation object 의 생명주기는?

"앞서 
 Activation object 에 대해 설명 한 것 처럼 Activation object의 생명 주기는
함수가 종료되고 실행 컨텍스트가 소멸 될 때 같이 소멸 됩니다
.

즉, 실행 컨텍스트가 소멸 될때 Activation object도 같이 소멸 된다는 말과 같습니다.


하지만, closer 생성시 [[Scope]]속성 초기화 과정에서 포함된 Activation object

실행 컨텍스트에 포함 된게 아니라 [[Scope]]에 포함 되었기 때문에 함수 종료시 소멸
되지 않습니다
.

즉, 메모리에 영구적으로 적재 된다는 말입니다.


결국 이로인해 IE 메모리 누수 현상이 발생 하는 것 입니다.

9. fnScope의 Activation object 생명 주기는 함수가 종료 될 때 같이 소멸 됩니다.




위 그림을 코드로 표현하면 아래와 같습니다.


  1. // 함수 생성
  2. function fnScope(num1, num2){
  3.    
  4.     var sum = num1 + num2;
  5.    
  6.     //클로져
  7.     function scopeFunction(){
  8.         var closer_variable = 2;
  9.         return sum + closer_variable;
  10.     }
  11.  
  12.     return sum;
  13. }



6. closer 실행


closer 발생 함수를 실행합니다.




1. closer 실행실행 컨텍스트 객체가 생성됩니다.

2. 실행 컨텍스트도 자신만의 식별자 검색을 위한 "
Scope chain"을 포함 합니다.


3. "Scope Chain"은 함수의 [[Scope]] 속성에 있는 전역 객체(Global object)로 
초기화
 됩니다.


4. 초기화 과정이 끝나면 Activation object(활성화 객체) "Scope Chain" 에 추가 
됩니다.


5. Activation object 는 "this", "Aguments 집합", "지역변수", 
"매개변수" 항목을 
포함 합니다.
  


6. closer의 Activation object 생명 주기는 함수가 종료 될 때 같이 소멸 되며, closer 생성시 closer의 [[Scope]] 속성으로 초기화된 fnScope의 실행 컨텍스트 객체(Activation object, global object)는 소멸되지 않고 영구적으로 메모리에 적재 됩니다.




위 그림을 코드로 표현하면 아래와 같습니다.


  1. function fnScope(num1, num2){
  2.    
  3.     var sum = num1 + num2;
  4.    
  5.     //클로져
  6.     function scopeFunction(){
  7.         var closer_variable = 2;
  8.         return sum + closer_variable;
  9.     }
  10.  
  11.     return sum;
  12. }
  13.  
  14. fnScope(5, 10); // 함수 실행