javascript

Javascript에서 Scope (4) - Element Object에서 this

단순대왕 2012. 4. 13. 15:32

이번에는 Element Object에서 어떻게 this가 활용되는지 알아 보겠습니다.
지난번 글에서 this가 Object 내부의 함수에서 사용(evaluation)될 때, this가 해당 Object를 참조한다는 것을 알아 보았습니다.

마찬가지로, Element Object내의 함수에서 this가 사용되면 this는 해당 Element를 참조하게 됩니다. HTML+JS 를 통해서 이를 살펴보도록 하겠습니다.


#1. HTML에서의 Event 등록과 JS에서의 Event 등록의 차이

<input id="button" type="button" />

function eventButtonClick() {
     element = document.getElementById("button");
    (this == window).print("this == window");
    (this == element).print("this == element");
}


document.getElementById("button").onclick = eventButtonClick;


(결과)
> this == window: false
> this == element: true


위와 같이 Script에서 onClick에 해당 함수를 넣을 경우에 해당 Button을 클릭하면, this가 해당 element 나오는 것을 알 수 있습니다.

<input id="button" type="button" onclick="eventButtonClick()" />


function eventButtonClick() {
    element = document.getElementById("button");

    (this == window).print("this == window");

    (this == element).print("this == element");

}
(결과)
> this == window: true

> this == element: false


반면에.. HTML에서 해당 Event에 함수를 지정한 경우에는
해당 Button을 클릭할 때, this는 window가 나오는 것을 알 수 있습니다.




#2. 차이가 발생하는 이유

도대체 왜 이런 차이가 생기는 것일까요?
일단 Click 이벤트가 발생이 되면.. 
document.getElementById("button").onclick();
와 같은 방식으로 해당 이벤트 핸들러가 호출 됩니다. 

이때 함수 내부에 어떠한 차이가 있는지 각각의 경우에 함수 내부의 모습을 출력 해보도록 하겠습니다.

<input id="button" type="button" onclick="eventButtonClick()" />

function eventButtonClick() {
   (this == window).print("this == window");
}

document.getElementById("button").onclick.print("HTML");
document.getElementById("button").onclick = eventButtonClick;
document.getElementById("button").onclick.print("Script");

(결과)
> HTML: function anonymous() { eventButtonClick(); }
> Script: function eventButtonClick() { (this == window).print("this == element"); }


Script에서 이벤트 메소드에 함수를 지정하면, 해당 함수 Object가 직접 할당 시키는 효과를 가지지만, HTML에서 함수를 지정하면 해당 부분이 String으로 되어 있기 때문에 함수 Object가 직접 할당 되지 않고, anonymous 함수 내부에서 evaluation 되는 형태로 지정되게 됩니다.

즉, Script에서 이벤트 등록을 위해서 실행 되는 코드는... 

element.onclick = function() { alert(this); }

와 같다고 한다면. HTML에서 이벤트 등록을 위해서 실행되는 코드는..

var func = function() { alert(this); }
element.onclick = function() { func(); }

와 같이 된다고 할 수 있겠습니다. 
엄연한 차이가 발생합니다. 지난번 글을 유심히 보셨으면 위 둘 사이의 차이가 쉽게 보이실 것 같습니다.





#3. HTML에서도 Element Object의 this를 사용하기

그렇다면 HTML에서 Event를 지정하면서 this가 현재 Object를 참고하고 싶게 한다면 어떻게 해야 할까요?

<input id="button" type="button" onclick="eventButtonClick(this)" />

function eventButtonClick(sender) {
    element = document.getElementById("button");
    (sender == element).print("sender == element");
    (sender == window).print("sender == window");
}

(결과)
> sender == element: true
> sender == window: false
 

위 처럼 HTML에서 this를 적어 주면 됩니다.
이는 마치 위의 예제 형태로 단순화 시켜서 나타내면..

var func = function(sender) { alert(sender); }
element.onclick = function() { func(this); }

위와 같은 형식이 되겠습니다.
왠지 적고나니 지난번 글의 중복인것 같아서..
아래에 재미난(?) 퀴즈를 하나... ;;


##. 보너스 퀴즈

<input id="button" type="button" value="Element Object" />


var
 value = "Window Object";

var obj = function() {

    this.value = "Prototype Object";

    this.func = function() { this.value.print("Name"); };

    };

obj.value = "My Object";

obj.func = function() { this.value.print("Name"); }

document.getElementById("button").onclick = (빈칸)


위 코드에 보면 각 Object에 따라서 value값에 
(A) Element Object
(B) Window Object
(C) Prototype Object
(D) My Object
의 네 개의 값이 들어 있습니다.

button을 눌렀을 때, (A)~(D)의 String이 출력되도록 할려면 빈칸에 어떤 코드가 들어가야 할까요?