* JavaScript에서의 this 지시자

 JavaScript에서 this는 다른 언어에서와 마찬가지로, 해당 함수가 속해있는 객체를 가리킨다. 전역 함수의 경우에 this는 window 객체를 가리킨다.

다음의 예제는 hello 함수를 하나 선언한 후에, 서로 다른 클래스에서 hello 함수를 메소드로 등록하여 사용하는 예제이다.

function hello() 
{
alert("Hi, I'm "+ this.name);
}
function ClassA()
{
this.name = "A";
}
function ClassB()
{
this.name = "B";
}
var a = new ClassA;
a.hello = hello;
a.hello();
var b = new ClassB;
b.hello = hello;
b.hello();

 

* JavaScript의 이벤트 핸들러 등록 방법

 JavaScript에서 이벤트 핸들러를 등록하는 방법에는 세 가지가 있다.

1) [Object].addEventListener("name_of_event", fnHandler, bCapture);
 DOM에서 사용하는 방법이다. (IE에서는 지원하지 않는다.) 여러 개의 이벤트 핸들러를 등록할 수 있다.

2) [Object].attachEvent("name_of_event_handler", fnHandler);
 IE 에서 사용하는 방법이다. MSIE에서는 이벤트가 발생했을 때, capturing phase가 없기 때문에 이 함수에는 세번째 인자가 없다. addEventListener 함수를 사용할 때, bCapture=false로 한 것과 같다. 역시 여러 개의 이벤트 핸들러를 등록할 수 있다.

3) [Object].name_of_event_handler = fnHandler;
 JavaScript에서 이벤트 핸들러를 등록하는 전통적인 방법인 대입법이다. 호환성이 좋으나 이벤트 핸들러를 하나밖에 등록할 수 없다.

 그래서, 여러 브라우저에서 동작하도록 이벤트 핸들러 등록 함수를 만들때 다음과 같이 한다. Professional JavaScript for Web Developers(Wrox) p.292에 나온 예제이다.

EventUtil.addEventHandler = function (oTarget, sEventType, fnHandler) 
{
if (oTarget.addEventListener)
{ //for DOM-compliant browsers
oTarget.addEventListener(sEventType, fnHandler, false);
}
else if (oTarget.attachEvent)
{ //for IE
oTarget.attachEvent("on" + sEventType, fnHandler);
}
else
{ //for all others
oTarget["on" + sEventType] = fnHandler;
}
};

 정말 이렇게 사용해도 될까?

 대부분의 경우에는 문제 없이 동작할 것이다. 하지만, fnHandler 안에서 this를 사용한다면 문제가 될 수 있다. attachEvent 함수를 통해서 등록된 이벤트 핸들러와 대입법으로 등록된 이벤트 핸들러에 대한 IE의 내부적인 동작 방식이 다르기 때문이다.

 다음의 예제를 보자.

function onClickEventHandler(event) 
{
if (this == window)
{
alert("This is the window object");
}
else
{
alert(this.tagName);
}
}
myObject.onclick = onClickEventHandler;
myObject.attachEvent("onclick", onClickEventHandler);

 위와 같이 이벤트 핸들러를 작성하여 테스트를 해 보면 차이점을 좀더 확실히 알 수 있다. 같은 객체에 대해 이벤트 핸들러를 두 개 등록했으며, myObject 객체를 클릭하면 alert 창이 두 번 나타날 것을 예상할 수 있다. 하지만 그 메시지의 내용은 다를 것이다.

 대입법으로 이벤트 핸들러를 등록하면, 그 이벤트 핸들러 함수는 해당 객체의 메소드처럼 동작한다. 반면에 attachEvent 함수를 사용하여 등록하면, 이벤트가 발생했을 때 호출될 뿐이지 해당 객체의 메소드가 되는 것은 아니다. 또한, 호출되는 순서도 정해져 있다. 대입법으로 등록된 이벤트 핸들러가 먼저 호출된 후에, attachEvent 함수로 등록된 이벤트 핸들러가 호출된다. attachEvent함수로 등록된 이벤트 핸들러들끼리는 호출 순서의 규칙이 없고 랜덤하게 호출된다. (addEventListener 함수로 등록된 이벤트 핸들러는 등록된 순서대로 호출된다.) 그러므로 위 예제에서 이벤트 핸들러의 등록 순서를 다음과 같이 바꿔도 실제 호출되는 순서는 변함이 없다.

myObject.attachEvent("onclick", onClickEventHandler);
myObject.onclick = onClickEventHandler;

 Professional JavaScript for Web Developers(Wrox Press, 2005)에서는 등록할 수 있는 핸들러의 개수만 빼고 모두 같은 거라고 되어있고 이러한 차이점에 대한 언급이 없다. MSDN에는 이런 차이점이 잘 설명되어 있으므로, Microsoft 관련한 의문사항은 MSDN을 살펴보는 습관을 기르자. ㅡㅂㅡ;

===================================================================================================================

출처 : http://mashedon.egloos.com/1484422

AND