본문 바로가기

Javascript

Javascript module, 공통 함수 만들기 정리

이번에 공통 함수를 만들 일이 생겼다. 

처음에는 그냥 공통 스크립트 파일에 전역 변수로 만들려다가 문득 그건 좀 아닌 거 같다는 생각이 들었고

제대로 만들어야 할 것 같아서 이번 기회에 정리를 좀 해볼까 한다.

출처는 대부분이 '속 깊은 자바스크립트'다.


1. 그냥 전역변수로 만든 경우

<script>   

    function test(){

    alert('real test function');

    };


   test(); // real test function

</script>


문제점 - 다른 test() 함수가 있는 경우 덮어쓰기가 가능하다.

아래와 같이 동일한 function 이 있는 경우 덮어쓰기 돼서 나중에 만든 test()가 호출된다. 

<script>   

    function test(){

     alert('real test function');

    };


    function test(){

   alert('same name test function');

    };


test(); // same name test function!

</script>


또는 이런 즉시실행함수가 있는 경우도 덮어쓰기 가능.

<script>

test();


(function(window){

    window.test = function(){

    alert('fake test fuction! haha');

    }

    }(window));

</script>

// 결과는 fake test fuction! haha

의도치 않게 다른 개발자가 만든 함수 이름과 겹치는 경우 요런 문제가 발생할 수 있으므로, 전역 변수 사용은 이제 그만하자.



2. 모듈 생성 후 window로 노출

<script>

    (function(window){

    var module1 = {

    name : function(){

    alert('module1 in first')

    },

    hello : function(){

    alert('say hello in first');

    }

    }

   

    window.module1 = module1;

    }(window));

        

    module1.name(); // module1 in first

</script>


요런식으로, window 객체를 넘겨주고 window에 module1을 담는다.

그런데 이때, 아래와 같이 module1이라는 변수명을 사용하는 다른 함수가 있다면 

또 의도치 않게 덮어쓰기가 발생할 수 있다.

<script>

    (function(window){

    var module1 = {

    name : function(){

    alert('module1 in first')

    },

    hello : function(){

    alert('say hello in first');

    }

    }

   

    window.module1 = module1;

    }(window));

    

    (function(window){

    var module1 = {

    name : function(){

    alert('module1 in second')

    }

   

   

    window.module1 = module1;

    }(window));


module1.name(); // module1 in second

</script>


이러면 또 곤란하다. 

jQuery의 경우 window에 $ 변수가 이미 있는 경우, _$에 백업해두고, jQuery에 없는 함수가 호출되는 경우 

_$에서 함수를 호출하도록 처리했다고 한다. 이런 꼼꼼한 놈들.. 


그래서 비슷하게 흉내를 내보면,

(function(window){

    var module1 = {

    name : function(){

    alert('module1 in second')

    }

    }

   

  // 백업 코드 추가..

    var _module1;

    if(window.module1){

    _module1 = window.module1;

   

    for(key in _module1){

    if(!module1[key]){

    console.log(key+'는 second의 module1에는 없는 변수네요. first의 module1에 있는 변수를 참조할 수 있도록 조치합니다.');

    module1[key] = _module1[key]; //_module1의 변수를 module1에 담는다.

    }

    }

    }

   

    window.module1 = module1;

    }(window));


module1.name(); // module1 in second

module1.hello(); // say hello in first

이런식으로 name은 second의 함수를 호출하고, second에 없는 hello 함수를 호출한 경우에는 first의 hello 함수를 호출하도록 할 수 있다.


3. 전역변수에 모듈 할당

<script>

    var moduleTest3;

    (function(window){

    var module1 = {

    name : function(){

    alert('module1 in moduleTest3!!')

    }

    }

   

    moduleTest3 = module1;

    }(window));

    

    var moduleTest4 = (function(window){

    var module1 = {

    name : function(){

    alert('module1 in moduleTest4!!')

    }

    }

   

    return module1;

    }(window));


moduleTest3.name(); //module1 in moduleTest3!!

moduleTest4.name(); //module1 in moduleTest4!!

</script>

이건 뭐 딱히 설명이 필요 없다.


어찌 됐든 이와같이 모듈로 만들어 사용하려면 전역변수를 최소 하나는 생성을 할 수밖에 없다.

다 작성하고 보니... 함수명이 중복되는 가능성은 항상 존재한다.

뭐 그래도 함수1, 함수2, 함수3을 전역변수로 만든는 것 보다는

모듈화해서 하나의 모듈함수 안에 넣어서 쓰는게 훨씬 바람직한 건 사실이니...


아무튼 이를 방지하기 위해 네임스페이스를 사용하는데, 

그건 http://unikys.tistory.com/250 여기에 설명이 잘 나와있다.


이제 모듈 만들때 헤매지 말자.

그리고 다음에는.. prototype 정리를 해볼까 한다. 


'Javascript' 카테고리의 다른 글

jQuery create form  (0) 2018.05.15
for loop javascript  (0) 2017.12.20
jstl에서도 동적 매핑이 가능하다.  (0) 2017.06.29
jstl fn substring으로 날짜 앞에 0붙이기  (1) 2017.02.28
동기화 처리  (0) 2017.01.06