Una de las palabras clave más poderosas de JavaScript es "this
". Desafortunadamente es difícil de usar si no sabes exactamente cómo funciona.
A continuación explico cómo utilizarlo en
gestión de eventos.
Más adelante añado alguna información sobre otros usos de this
.
La pregunta que discutiremos a lo largo de la página es la siguiente: ¿A qué se refiere this
en la función doSomething()
?
function doSomething() { this.style.color = '#cc0000'; }
En JavaScript this
siempre se refiere al propietario de la función que estamos ejecutando,
o mejor dicho, al objeto del cual la función es un método. Cuando definimos nuestra función doSomething()
en una página,
su propietario es la página, es decir, el objeto window
(u objeto global)
de JavaScript. Un onclick
, en cambio, es propiedad del elemento HTML al que pertenece.
Esta propiedad es el resultado del enfoque orientado a objetos de JavaScript. Ver la web objetos como matrices asociativas para más información.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | -------------------- | | | onclick property | | | -------------------- | | | ----------------------------------------------------------
Si ejecutamos doSomething()
sin más elaboración, la palabra clave this
se refiere a la ventana, y la función intenta cambiar el style.color
de la ventana.
Dado que esta no tiene un objeto style
, la función falla y produce errores de JavaScript.
Así que, si queremos usar this
en toda su extensión, debemos ser cuidadosos y asegurarnos de que la función
que lo usa es propiedad del elemento HTML correcto. En otras palabras, tenemos que
copiar la función de nuestra propiedad onclick.
El registro de eventos tradicional se encarga de este asunto.
element.onclick = doSomething;
La función se copia en su totalidad a la propiedad onclick
(que ahora se convierte en un método).
Si el controlador de eventos ejecuta this
, este se refiere al elemento HTML y su color
es cambiado.
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
El truco es, por supuesto, que podemos copiar la función a varios controladores de eventos.
Donde respectivamente
------------ window -------------------------------------- | | | | | | | ---------------- | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | | | | ----------------------- | | | | another HTML element| <-- this | | | ----------------------- | | | | | | | | | ----------------------- | | | |copy of doSomething()| <-- copy function | | ----------------------- | | | ----------------------------------------------------------
Por lo tanto, se utiliza this
en su máxima extensión. Cada vez que se llama a la función,
this
se refiere al elemento HTML que está manejando el evento; el elemento HTML
que "posee" la copia de doSomething()
.
Sin embargo, si utilizamos el registro de eventos en línea
element onclick="doSomething()";
no se está copiando la función! Sino que nos estamos refiriendo ella, y esta diferencia es crucial.
La propiedad onclick
no contiene la función real, sino una simple referencia a la función:
doSomething();
En este caso el resultado sería “Ir a doSomething() y ejecutarlo.” Cuando
llegamos a doSomething()
la palabra clave this
, una vez más, se refiere a la palabra clave global
y la función devuelve mensajes de error.
------------ window -------------------------------------- | / \ | | | | | this | | ---------------- | | | | HTML element | <-- this ----------------- | | ---------------- | | doSomething() | | | | | ----------------- | | ----------------------- / \ | | | go to doSomething() | | | | | and execute it | ---- reference to | | ----------------------- function | | | ----------------------------------------------------------
Si desea utilizar this
para acceder al elemento HTML que gestiona el evento,
debe asegurarse de que la palabra clave this
está realmente escrita en la propiedad onclick
.
Sólo en ese caso se refiere al elemento HTML en el que está registrado el manejador de eventos.
a. Así que si escribes
element.onclick = doSomething; alert(element.onclick)
obtendrás
function doSomething() { this.style.color = '#cc0000'; }
Como puede ver, la palabra clave this
está presente en el método onclick
.
Por lo tanto, se refiere al elemento HTML.
En cambio, si escribieras
; alert(element.onclick)
obtendrías
function onclick() { doSomething() }
Esto sería simplemente una referencia a la función doSomething()
. Donde la palabra clave onclick
, y donde por lo tanto no se estaría haciendo referencia al elemento HTML.
this
se escribe en el método onclick
en los casos siguientes:
element.onclick = doSomething element.addEventListener('click',doSomething,false) element.onclick = function () {this.style.color = '#cc0000';};
En los casos siguientes this
refiere a la ventana:
element.onclick = function () {doSomething()} element.attachEvent('onclick',doSomething);
Observe la presencia de attachEvent()
. El principal inconveniente del
modelo de registro de eventos de Microsoft
es que attachEvent()
crea una referencia a la función y
no lo copia. Por lo tanto, a veces es imposible saber qué HTML maneja actualmente
el evento.
Al utilizar el registro de eventos en línea, también puede
enviar
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'; }