먼저 이벤트 처리(이벤트 처리)에서 어떻게 사용하는지 이야기한 다음, 이것의 다른 용도에 대해 이야기해 보겠습니다.
먼저 doSomething() 함수에서 이것이 가리키는(참조) 것이 정확히 무엇인지 살펴보겠습니다.
function doSomething() { this.style.color = '#cc0000'; }
JavaScript의 this는 항상 실행 중인 함수 "자체"를 가리킵니다. 즉, 함수객체를 가리키는 메소드이다. 페이지에 doSomething() 함수를 정의하고 그 자체가 페이지를 참조합니다. 즉, 자바스크립트 윈도우 객체(전역객체)를 의미합니다. onclick 속성 자체는 HTML 요소에 속합니다.
이 "소유권"은 JavaScript의 OO(객체 지향) 특성에 따른 결과입니다. 자세한 내용은 객체를 연관 배열로 만들기 페이지를 참조하세요.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | -------------------- | | | onclick property | | | -------------------- | | | ----------------------------------------------------------
doSomething()이 관련 예약 없이 실행되면 키워드 this는 윈도우(window)를 가리키며, 이 함수는 윈도우의 style.color를 변경합니다. 그리고 창에는 스타일과 같은 개체가 없으므로 이 함수는 JavaScript 오류를 발생시킵니다.
그래서 이걸 잘 활용하기는 좀 어렵네요. 함수에 사용될 때 위 예제의 경우와 마찬가지로 HTML 요소 "자체"를 가리켜야 합니다. 즉, onclick 속성을 가리키는 함수의 복사본이 있습니다. 전통행사등록에서 어떤 일이 일어나는지 살펴보겠습니다.
element.onclick = doSomething;
copy all 함수는 onclick 속성(현재는 메소드)을 가리키기 때문에 이벤트 핸들러가 실행되면 HTML 요소를 가리키며 색상이 변경됩니다.
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
이를 통해 여러 이벤트 핸들러에 대한 함수 복사본을 제공할 수 있습니다. 매번 올바른 HTML 요소를 가리킵니다:
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | | | | ----------------------- | | | | another HTML element| <-- this | | | ----------------------- | | | | | | | | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
함수가 호출될 때마다 이는 현재 이벤트를 처리하는 HTML 요소("자체" doSomething()의 복사본)를 가리킵니다.
인라인 이벤트 등록을 사용하면 어떨까요?
<element onclick="doSomething()">
여기에는 복사 기능이 없는데 가리키기만 하면 무슨 차이가 있나요? onclick 속성에는 실제 함수가 없고 함수 호출만 포함됩니다.
doSomething();
위의 의미는 "doSomething()으로 이동하여 실행"입니다. doSomething()에서 this 키워드는 다시 전역 창 개체를 가리키며, 그러면 함수는 오류 메시지를 반환합니다.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- / \ | | | go to doSomething() | | | | | and execute it | ---- reference to | | ----------------------- function | | | ----------------------------------------------------------
이를 사용하여 이벤트를 처리하기 위해 HTML 요소에 액세스하는 경우 실제로 onclick 속성에 기록되는지 확인해야 합니다. 그리고 HTML 요소를 가리키는 이벤트 핸들러도 등록됩니다. 이렇게 하면:
element.onclick = doSomething; alert(element.onclick)
당신이 얻는 것은
function doSomething() { this.style.color = '#cc0000'; }
보시다시피 이 키워드는 onclick 메소드에 있습니다. 이는 HTML 요소를 가리킵니다.
하지만 이렇게 하면:
<element onclick="doSomething()"> alert(element.onclick)
당신이 얻는 것은
function onclick() { doSomething() }
이것은 단지 doSomething() 함수를 가리킵니다. 이 키워드는 onclick 메소드에 없습니다. HTML 요소를 가리키지 않습니다.
다음 예에서는 onclick 메소드로 작성되었습니다.
element.onclick = function () {doSomething()} element.attachEvent('onclick',doSomething) <element onclick="doSomething()">
다음 예에서 이는 창을 가리킵니다.
element.onclick = function () {doSomething()} element.attachEvent('onclick',doSomething) <element onclick="doSomething()">
위의 AttachEvent에 주목하세요. 단점은 Microsoft 이벤트 등록 모델이 함수에 대한 포인터를 생성하고 복사하지 않는다는 것입니다. 따라서 어떤 HTML 이벤트가 현재 처리되고 있는지 파악하는 것이 불가능한 경우도 있습니다.
인라인 이벤트 등록을 사용할 때 이를 함수에 보낼 수도 있습니다. 따라서 다음과 같이 사용할 수 있습니다.
<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'; }