Uninstallme

La Web se ideó cuadrada.

POO en javascript: uso y ámbito de this

26 de Septiembre 2008

En las diapositivas del post anterior sobre este tema, explicaba la sintaxis de la notación literal de objetos y comentaba el uso de la palabra reservada this para acceder a las propiedades y métodos de un objeto.

Ejemplo de uso de this:


var Mensaje = function(){};
// Extiendo los métodos y propiedades de mi objeto con prototype
Mensaje.prototype = { 

	// propiedades de "Mensaje"
	mensaje: 'Hola mundo',
	identificadorLinkAlerta: 'alerta',  

	// método de "Mensaje"
	inicio: function(){
		// llamo a un método de mi objeto "Mensaje" usando this
		this.muestraAlerta();
	},

	// método de "Mensaje"
	muestraAlerta: function(){
		// accedo a una propiedad de mi objeto "Mensaje" usando this
		var linkAlerta = document.getElementById(this.identificadorLinkAlerta); 

		// haz cosas con linkAlerta...
	}
}

Se podría haber hecho lo mismo usando el nombre del Objeto en lugar de la palabra reservada this, pero de esta manera, los nuevos objetos creados como instancias del objeto inicial no funcionarían, ya que en NombreObjeto.metodo() o NombreObjeto.propiedad, “NombreObjeto” no haría referencia al objeto propietario de esos métodos o propiedades en cada caso.

Ejemplo usando el nombre del objeto en vez de this:


// Objeto inicial o Clase (función constructora)
var Mensaje = function(){};
Mensaje.prototype = {
	mensaje: 'Hola mundo',
	identificadorLinkAlerta: 'alerta',  

	inicio: function(){
		// llamo a un método de mi objeto "Mensaje" usando el nombre del objeto "Mensaje"
		Mensaje.muestraAlerta();
	},

	muestraAlerta: function(){
		// accedo a una propiedad de mi objeto "Mensaje" usando el nombre del objeto "Mensaje"
		var linkAlerta = document.getElementById(Mensaje.identificadorLinkAlerta); 

		// haz cosas con linkAlerta...
	}
}

// Nuevo objeto (instancia de "Mensaje") que no funcionará
var instanciaMensaje = new Mensaje();
instanciaMensaje.inicio();

En este ejemplo, el objeto instanciaMensaje no funcionará, ya que no se ha usado this en la función constructora.

Ámbito de this

La palabra reservada this hace referencia al elemento u objeto dueño de la función en la que se encuentra, por eso es bastante probable que this no siempre haga referencia a nuestro objeto “Mensaje”.


mensaje: 'Hola mundo',
...
muestraAlerta: function(){
	var linkAlerta = document.getElementById(this.identificadorLinkAlerta);
	linkAlerta.onclick = function(){
		alert(this.mensaje); // this hace referencia a linkAlerta
	}
}

La alerta mostrará “undefined”, ya que this se está refiriendo en este caso al elemento “linkAlerta” en vez de al objeto “Mensaje”.

Para evitar esto podemos recurrir a varias técnicas.

La más sencilla y quizá menos elegante, es asignar el valor de this a una variable en un punto en el que haga referencia al objeto al que queremos referirnos.

Ejemplo:


muestraAlerta: function(){
	var that = this;
	var linkAlerta = document.getElementById(this.identificadorLinkAlerta);
	linkAlerta.onclick = function(){
		alert(that.mensaje); // that hace referencia al objeto "Mensaje"
	}
}

Aunque en este caso, simplemente podríamos haber asignado el valor de Mensaje.mensaje a una variable.


muestraAlerta: function(){
	var msg = this.mensaje;
	var linkAlerta = document.getElementById(this.identificadorLinkAlerta);
	linkAlerta.onclick = function(){
		alert(msg);
	}
}

Otra posibilidad es usar with (this). De esta forma no necesitaremos usar la palabra reservada this dentro de las instrucciones de nuestro método para referirnos al objeto “Mensaje”

Ejemplo usando with(this):


muestraAlerta: function(){ with (this) {
	var linkAlerta = document.getElementById(identificadorLinkAlerta);
	linkAlerta.onclick = function(){
		alert(mensaje);
	}
}} // Doble llave de cierre

Los frameworks javascript suelen ofrecen el método bind() para este fin. bind() permite que this haga referencia al objeto que se le pase como argumento.

Ejemplo usando bind() con Prototype o Mootools:


muestraAlerta: function(){
	var linkAlerta = document.getElementById(this.identificadorLinkAlerta);
	linkAlerta.onclick = function(){
		alert(this.mensaje);
	}.bind(this);
}

JQuery, que va un poco a su bola y a mí personalmente dejó de gustarme porque se parece poco a Javascript, también dispone de un método bind() que no tiene la misma función que el de Prototype, Mootools y otras librerías, sino que sirve para añadir eventos a un elemento. Es decir, equivale al observe() de Prototype o addEvent() de Mootools.

Más información:

Archivado en How to, Javascript

Deja tu comentario

Campos obligatorios marcados con *