이번에 공통 함수를 만들 일이 생겼다.
처음에는 그냥 공통 스크립트 파일에 전역 변수로 만들려다가 문득 그건 좀 아닌 거 같다는 생각이 들었고
제대로 만들어야 할 것 같아서 이번 기회에 정리를 좀 해볼까 한다.
출처는 대부분이 '속 깊은 자바스크립트'다.
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 |