자바스크립트 즉시 실행 함수의 불편한 진실

Posted by RAY.D
2015. 4. 16. 05:44 Web/javascript / jQuery
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

출처 : http://blog.jidolstar.com/814

 

 

 

자바스크립트에 함수를 정의하는 방법은 함수 객체(Function)을 사용하는 방법과 연산자인 function을 사용하는 방법이 있습니다. 이 중에서도 function의 경우 함수 선언문과 함수 표현식이 있습니다. 


함수 선언문은 다음과 같이 쓸 때 함수 선언문이라고 합니다.


function foo() {

}


그외에 방법은 전부 함수 표현식입니다.


a = function() {}; //익명 함수 표현식

a = function a() {};  //기명 함수 표현식

(function a() {})();  //즉시 실행 기명 함수 표현식

(function (){})();  //즉시 실행 익명 함수 표현식


함수선언문과 함수표현식에 대해서는 다른 제 블로그 글에 많이 나오므로 검색해서 보세요.


함수 선언문의 경우 자바스크립트 인터프리터가 바로 해석해서 부모 함수의 스코프 영역에 등록합니다. 그래서 함수 선언문의 경우 실제로 실행할 때 어느 위치에서 호출하든 문제가 발생하지 않습니다. 


하지만 함수 표현식의 경우 실행할 때 해석하는 방식으로 동작합니다. 그렇기 때문에 호출시점이 선언시점보다 먼저 있다면 정의되지 않은 함수가 됩니다. 


여기서 더 다룰 내용은 바로 함수 표현식중에서는 즉시 실행 함수입니다. 함수가 정의되지 마자 바로 실행해 버리는 즉시 실행 함수는 꽤 유용합니다. 많은 책에서 이 패턴을 "초기화 코드에 유효범위 샌드박스(sandbox)를 제공해서 유용하다."라는 이유로 사용을 권장합니다. 이 패턴과 유사한게 즉시 객체 초기화라는 것이 있습니다. 다음과 같은 형태죠.


({

     maxwidth: 600,

     maxheight : 400,

     init: function() {

              ….

     };

}).init();


즉시 객체 초기화 패턴도 전역 영역을 더럽히지 않는다는 면에서 즉시 실행 함수 패턴과 비슷한 장점을 가집니다. 


자, 그럼 다음 것은 어떨까요?


3; 


저렇게만 쓰만 자바스크립트가 잘 동작하나요?


답은 문제없이 해석하고 동작합니다. 어떤 동작을 하나요? 아무것도 안합니다. 하지만 해석은 하겠죠? 여기서 즉시 실행 함수와 즉시 객체 초기화 패턴이 3; 이라고 코딩한 것과의 공통점은 무엇일까요? 그것은 할당 없이 리터럴 값만을 정의했다는 점입니다.


자바스크립트는 저렇게 할당없이 정의부만 있는 경우 EC(실행 컨텍스트)에 key-value로 temp = [] 내에 실행 타임에 추가를 합니다. 굳이 적어본다면 아래처럼 해석해버리고 실행합니다.


(function (){})();

({ …init:function() {}; }).init();

3; 


EC.temp = [   (function (){})() 

, ({ …init:function() {}; }).init()

,  3 ];



문제가 무엇일까요? 제가 이번 글에서 강조하고 싶은 것은 이런 패턴을 남용하면 메모리 낭비가 될 수도 있다는 것입니다. 이 공간은 개발자가 접근할 수 없기 때문에 전역에 저것을 남용하면 결국 window의 EC.temp = [];에 들어가는 것이기 때문에 많은 메모리를 낭비할 수 있습니다. 실제로 YUI가 저런 패턴을 너무 많이 써서 메모리 낭비가 심한 편이라고 합니다. 


할당 없이 리터럴 형태만 정의한 즉시 실행 함수, 즉시 객체 초기화등은 전역 이름 공간을 더럽히지 않는다는 점은 EC.temp 영역은 개발자가 접근할 수 없으므로 어짜피 모르는 영역이고 각종 스코프 체인 및 프로토타입 체인등의 key-value 검색에도 들어가지 않는다는데서 기인한 것이지 메모리를 사용하지 않는다는 말은 아닌겁니다. 


오히려 메모리를 낭비하지 않고 즉시 실행 함수처럼 사용하고 싶다면 다음 처럼 쓰면 될 것입니다.


a = function () {

};

a();

delete a; 



아무리 좋은 패턴도 장, 단이 있다는 점을 명심하고 적절하게 잘 사용해야 할 것입니다. ^^


jQuery는 즉시실행함수를 정말 잘 활용하고 있지요.