본문 바로가기

Programing/Javascript

javascript this

javascript의 this에 대해서 궁금했는데 잘 설명해 놓은 글이 있어서 링크해놓는다. 

http://www.quirksmode.org/js/this.html


Owner


아래에서 this는 어떤 것을 가리키고 있을까? 


function doSomething() {

   this.style.color = '#cc0000';

}


자바스크립트에서 this는 항상 "owner"를 가리킨다. owner란 function을 실행시킨 객체를 가리키며 다른말로, function을 소유하고 있는 object라고 이해하면 되겠다. 위에서 this는 window object를 가리킨다. 


------------ window --------------------------------------

|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------


만약 doSomething()이 저 상태에서 불려진다면 this 키워드는 window를 가리키고 윈도우의 style.color를 변경하려 들것이다. 

그러나 윈도우에는 style 객체를 가지고 있지 않기때문에 function은 실행 중 에러가 나게된다. 



Copying


따라서 만약 this를 제대로 사용하고 싶다면 올바른 HTML element에 "owned(소유)" 될 수 있도록 해야한다. 

다시말해, copy를 해야한다는 것이다. Traditional event registration 라고 부르는 방법이다. 


element.onclick = doSomething;


요래하면 function은 완전하게 onclick으로 copy된다. (onclick은 이제 method가 되었다.) 따라서 이제 onclick 이벤트가 일어나면 this는 element라는 HTML element를 가리키게된다. 


------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        | 

----------------------------------------------------------


이제 이런 트릭으로 우리는 doSomething() function을 여러 이벤트 핸들러에게 넘겨줄 수 있게 되었다. 

이벤트가 발생할 때마다 this는 올바른 HTML element를 가리키게 될 것이다. 


------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------          |            |
|                                           |            |
|   -----------------------                 |            |
|   | another HTML element| <-- this        |            |
|   -----------------------     |           |            |
|               |               |           |            |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        | 

----------------------------------------------------------



그러므로 이제 function이 호출될 때마다 doSomething의 this는 소유된 각 HTML element를 가리키게 될 것이다. 


Referring

하지만 만약 inline event registration을 사용한다면


<element onclick="doSomething()">


당신은 function을 copy한 것이 아니다! 대신 그냥 참조할 뿐이고 이 차이는 중요하다. 

onclick property는 실제 function 내용을 담고 있지 않고, 실제로는 단지 호출하기만 할 뿐이다. 


doSomething();

그러므로 이것은 "doSomething() 함수로 가서 이것을 실행하라"는 것이다. 

이렇게 실행됬을시에 doSomething()에 다다르면 this 키워드는 global window를 가리키게 되며 맨처음의 예에서와 같은 이유로 에러가 난다. 

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        | 
----------------------------------------------------------


The difference

이벤트를 핸들링 하는 HTML element에 this로 접근하려 한다면 onclick property안에 실제로 this keyword가 들어가 있어야한다. 
그런 경우에만 이벤트 핸들링하는 HTML element를 this가 참조하게 된다. 

만약 아래와 같이 해보면

element.onclick = doSomething;
alert(element.onclick)    

다음과 같은 결과를 얻을 것이다. 

function doSomething()
{
this.style.color = '#cc0000';
}

this 키워드가 onclick method안에 실제 표현되어 있다. 그러므로 여기서 this는 HTML element를 가리킨다. 

그러나 만약 아래같이 한다면 

<element onclick="doSomething()">
alert(element.onclick)


다음과 같은 결과를 얻는다. 

function onclick()
{
doSomething()
}


이것은 단지 doSomething() 함수를 가리킬 뿐이다. 실제 실행시에는 doSomething에 가서 실행된다. 여기서 this 키워드는 onclick 함수에 존재하지 않는다. 따라서 여기서는 HTML element를 가리키지 않는다. 


그러면 copying과 referring을 하는 방법을 더 보자 

Examples - copying

아래의 case들에서는 this가 onclick 함수 내에 표현된다. 

element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">


Examples - referring

아래의 case들에서는 this가 window를 가리킨다. 
element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">

attachEvent()는  Microsoft event registration model 이며 이 함수는 함수를 copy하지 않고 referring한다. 


Combination

inline registration을 사용하더라도 this를 함수에 넘겨 줄 수 있기 때문에 아래와 같은 방법으로 호출 HTML element에 접근하는게 가능하다. 

<element onclick="doSomething(this)">

function doSomething(obj) {
// this is present in the event handler and is sent to the function
// obj now refers to the HTML element, so we can do
obj.style.color = '#cc0000';
}






'Programing > Javascript' 카테고리의 다른 글

javascript code beautify (pretty print)  (0) 2013.06.25
javascript class 상속  (0) 2012.06.28