요즘 prototype이 유행하고 있어서 잠깐 갖고 놀다가 문제점이 발생했습니다.
function KALSOME(id, str) {
var num = 0;
var str = str;
var int = null;
var obj = document.getElementById(id);
this.start = function() {
int = setInterval(this.foo, 500);
};
this.end = function() {
if(int) clearInterval(int);
};
this.foo = function() {
num++;
obj.value = str + " = " + num;
};
}
var kalsome_1 = new KALSOME("timer_1","성유리");
-----------------------------------------------------------------------------------------------------------
위에 소스는 잘됩니다. 그래서 prototype으로 확장성을 위해서 다음과 같이
바꿔보았습니다.
KALSOME = function(id, str) {
this.num = 0;
this.str = str;
this.int = null;
this.obj = document.getElementById(id);
}
KALSOME.prototype.start = function() {
this.int = setInterval(this.foo,500);
}
KALSOME.prototype.end = function() {
if(this.int) clearInterval(this.int);
}
KALSOME.prototype.foo = function() {
this.num++;
this.obj.value = this.str + " = " + this.num;
}
var kalsome_1 = new KALSOME("timer_1","성유리");
-----------------------------------------------------------------------------------------------------------
이렇게 하니까 foo() 함수가 실행이 안되는것이었습니다.
this.num = NaN 이 되고 this.str = undefined가 되고
this.obj는 개체가 없다고 댕댕거리더군요.
아무래도 수상해서 보니까 setInterval()로 호출된 함수는
KALSOME이 아니고 window 였습니다. ㅡㅡ;
그러니까 setInterval에서 호출될때 foo()죠.. 이것의 instance가
window로 둔갑한다는 겁니다. ㅡㅡ;
그러면 어떻게 하냐.. 무식이 짜장으로 var kalsome_1의 이름을 주냐?..
KALSOME.prototype.start = function() {
this.int = setInterval("kalsome_1.foo()",500);
}
이렇게 하니까 되기는 되는데, 너무 무식한것 같았습니다. ㅡㅡa
변수의 이름도 넘겨야 하니까요..
그래서 할 수 없이 구글링을 통해서 도움을 받았는데 이 문제 때문에
애 먹는 분이 계실까봐 포스팅 합니다.
먼저 해결방법은 다음과 같습니다.
KALSOME.prototype.start = function() {
var oInstance = this;
this.int = setInterval(function(){oInstance.foo()}, 500);
}
현재의 인스턴스가 window로 바뀌는것을 방지하기 위해서 인스턴스를
ANONYMOUS FUNCTION으로 만들어서 넘기는 방법입니다.
하여튼 양키들 대단합니다. ㅡㅡ;;
위에 예제 링크 보시면 쉽게 아실 수 있을겁니다.
양키 사이트 참고하실분은 아래 링크 클릭하세요. ^^
http://www.thescripts.com/forum/thread152277.html
ps. 예제 사이트를 올릴 수 있게 서버를 협찬해 주신 '우하루'님께 감사드립니다.
리플글.......
공대여자 07-09-20 19:09
예전에 저거 머리싸고 고민했지만
그냥 함수 하나 만들어서 넘기면 간단하죠.
window.setInterval 이라서
이 안에서 this를 하면 window가 되버리죠.
전에 저거 어떤분이 물어보신것 같은데....
예전에 저거 머리싸고 고민했지만
그냥 함수 하나 만들어서 넘기면 간단하죠.
window.setInterval 이라서
이 안에서 this를 하면 window가 되버리죠.
전에 저거 어떤분이 물어보신것 같은데....
L 07-09-21 00:37
아마 제가 물어봤을지도;;
자바스크립트 기본 개념이 없는지라.. 저 문제로 며칠 고민했네요
아마 제가 물어봤을지도;;
자바스크립트 기본 개념이 없는지라.. 저 문제로 며칠 고민했네요
칼솜 07-09-20 19:20
공대여자님 // 이렇게 하는것 말씀하는건가요?
KALSOME = function() {
this.index = KALSOME.instances.length;
KALSOME.instances[this.index] = this;
...
}
KALSOME.instances = [];
KALSOME.prototype.start = function() {
this.int = setInterval('KALSOME.instances['+this.index+'].foo()', 500);
}
공대여자님 // 이렇게 하는것 말씀하는건가요?
KALSOME = function() {
this.index = KALSOME.instances.length;
KALSOME.instances[this.index] = this;
...
}
KALSOME.instances = [];
KALSOME.prototype.start = function() {
this.int = setInterval('KALSOME.instances['+this.index+'].foo()', 500);
}
공대여자 07-09-20 20:25
아뇨 그냥 위 적힌 글과 같은방법을 사용했습니다.
뭐, 이것도 똑같군요.
아뇨 그냥 위 적힌 글과 같은방법을 사용했습니다.
뭐, 이것도 똑같군요.
거친마루 07-09-20 20:27
함수가 실행될 당시 스코프가 변해버려서 생기는 문제인데..
이럴때를 대비해서 Function.apply 라는게 있군요 : )
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply
You can assign a different this object when calling an existing function. this refers to the current object, the calling object. With apply, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
즉,
this.int = setInterval(this.foo.apply(this),500);
라고 하면 원하는 결과가 되겠네요
아...그나저나, 안녕하세요
오랜만에 로그인 =3=3
함수가 실행될 당시 스코프가 변해버려서 생기는 문제인데..
이럴때를 대비해서 Function.apply 라는게 있군요 : )
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply
You can assign a different this object when calling an existing function. this refers to the current object, the calling object. With apply, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
즉,
this.int = setInterval(this.foo.apply(this),500);
라고 하면 원하는 결과가 되겠네요
아...그나저나, 안녕하세요
오랜만에 로그인 =3=3
칼솜 07-09-20 20:47
공대여자님, 거친마루님 // 감사합니다. ^^
워... 별 방법이 다 있군요 ㅡㅡ;
ps. 에구.. 거친마루님 // Function.apply 하니까 한번만 실행되고 에러나네요 ㅡㅡ;
공대여자님, 거친마루님 // 감사합니다. ^^
워... 별 방법이 다 있군요 ㅡㅡ;
ps. 에구.. 거친마루님 // Function.apply 하니까 한번만 실행되고 에러나네요 ㅡㅡ;
거친마루 07-09-20 22:28
앗.. 그런식으로 만든게 있었는데 어딨는지 기억 안나요..
일단 도망 =3
앗.. 그런식으로 만든게 있었는데 어딨는지 기억 안나요..
일단 도망 =3
칼솜 07-09-20 23:06
그래도 한번이라도 실행되는것이 어딥니까? ^^
도망가지 마셈 ^^
그래도 한번이라도 실행되는것이 어딥니까? ^^
도망가지 마셈 ^^
Andrew.Ahn 07-09-21 02:25
http://jibbering.com/faq/faq_notes/closures.html#clSto
참고하시면 도움되실 듯 싶습니다.
http://jibbering.com/faq/faq_notes/closures.html#clSto
참고하시면 도움되실 듯 싶습니다.
칼솜 07-09-21 09:14
Andrew.Ahn님 // 감사합니다 ^^
일단 ANONYMOUS에서 잘되서 만족합니다만, 좋은 자료네요.
꼭 참고하겠습니다. ^^
Andrew.Ahn님 // 감사합니다 ^^
일단 ANONYMOUS에서 잘되서 만족합니다만, 좋은 자료네요.
꼭 참고하겠습니다. ^^
찌질찌질 07-09-21 11:46
전 뭐 복잡한건 모르고 저역시 무식이 짜장으로 만든 소스가있습니다.
<script>
KALSOME = function(id, str) {
me = this;
this.num = 0;
this.str = str;
this.int = null;
this.obj = document.getElementById(id);
}
KALSOME.prototype.start = function() {
this.int = setInterval(this.foo,500);
}
KALSOME.prototype.end = function() {
if(this.int) clearInterval(this.int);
}
KALSOME.prototype.foo = function() {
me.num++;
me.obj.value = me.str + " = " + me.num;
}
var kalsome_1 = new KALSOME("timer_1","성유리");
kalsome_1.start();
</script>
저도 이벤트를 통해 객체?내 함수가 실행되면 this가 변해버리더라구요
그래서 me = this; 하면 해결이 되더라구요 전 이런식으로 해결합니다
전 뭐 복잡한건 모르고 저역시 무식이 짜장으로 만든 소스가있습니다.
<script>
KALSOME = function(id, str) {
me = this;
this.num = 0;
this.str = str;
this.int = null;
this.obj = document.getElementById(id);
}
KALSOME.prototype.start = function() {
this.int = setInterval(this.foo,500);
}
KALSOME.prototype.end = function() {
if(this.int) clearInterval(this.int);
}
KALSOME.prototype.foo = function() {
me.num++;
me.obj.value = me.str + " = " + me.num;
}
var kalsome_1 = new KALSOME("timer_1","성유리");
kalsome_1.start();
</script>
저도 이벤트를 통해 객체?내 함수가 실행되면 this가 변해버리더라구요
그래서 me = this; 하면 해결이 되더라구요 전 이런식으로 해결합니다
칼솜 07-09-21 11:48
찌질찌질님 // 감사합니다. ^^
me라는 변수를 넣는 독특한 방식이군요. ^^
ps. 점심 먹고 테스트해 보았는데 new로 객체를 2개 받았더니
무조건 2번째 함수만 실행이 되더군요. me = window.me 변수로
동작하기 때문이라고 생각됩니다. 멀티로 돌릴 경우 배열로 처리해야
할것 같습니다.
찌질찌질님 // 감사합니다. ^^
me라는 변수를 넣는 독특한 방식이군요. ^^
ps. 점심 먹고 테스트해 보았는데 new로 객체를 2개 받았더니
무조건 2번째 함수만 실행이 되더군요. me = window.me 변수로
동작하기 때문이라고 생각됩니다. 멀티로 돌릴 경우 배열로 처리해야
할것 같습니다.
찌질찌질 07-09-21 13:34
헉. 그렇군요. me변수가 칼솜님말씀처럼 window.me변수로 되나보군요. 크응..
헉. 그렇군요. me변수가 칼솜님말씀처럼 window.me변수로 되나보군요. 크응..
공대여자 07-09-21 13:40
var this_c = this;
var fn =function(){this_c.xxxx();}
setInterval(fn,1000);
개인적으로 위처럼 사용합니다.
그냥
this_c = this
해버리면
this_c는 전역변수가 되버립니다.
밖에서 this_c = 'x'
해버리면 오류나겠죠.
var this_c = this;
var fn =function(){this_c.xxxx();}
setInterval(fn,1000);
개인적으로 위처럼 사용합니다.
그냥
this_c = this
해버리면
this_c는 전역변수가 되버립니다.
밖에서 this_c = 'x'
해버리면 오류나겠죠.
칼솜 07-09-21 14:53
공대여자님 // this_c에 this 넣고 function을 미리 함수 만들고
그것을 호출한것이군요. 역시 공대여자님입니다. ^^ (양키보다 우수하십니다)
그렇죠, this_c 하면 window.this_c가 되죠. ^^
펌:PHPSCHOOL
'인터넷정보' 카테고리의 다른 글
마우스 오버시 새창 띄우기 (0) | 2007.10.17 |
---|---|
마우스 오버시 새창 띄우기 (0) | 2007.10.17 |
WEB IME - 한글을 영어로 표기하기 :: 영문을 한글로.. (0) | 2007.10.17 |
WEB IME - 한글을 영어로 표기하기 :: 영문을 한글로.. (0) | 2007.10.17 |
자바스크립트 :: 객체 prototype에서 setInterval 문제점 (0) | 2007.10.17 |
자바스크립트 배열 검사 (0) | 2007.10.17 |
자바스크립트 배열 검사 (0) | 2007.10.17 |
다익스트라(Dijkstra) 알고리즘 (0) | 2007.10.17 |
다익스트라(Dijkstra) 알고리즘 (0) | 2007.10.17 |
TV, 영화에 사용된 폰트 (0) | 2007.10.17 |