Foros del Web » Programando para Internet » Javascript »

Dudas de novato - Javascript OO

Estas en el tema de Dudas de novato - Javascript OO en el foro de Javascript en Foros del Web. Buenas a todos. Estoy intentando aprender a programar Javascript orientado a objetos, y pese a entender qué es OO, me está costando el tema de ...
  #1 (permalink)  
Antiguo 06/03/2012, 02:52
 
Fecha de Ingreso: mayo-2008
Mensajes: 103
Antigüedad: 16 años
Puntos: 14
Dudas de novato - Javascript OO

Buenas a todos.

Estoy intentando aprender a programar Javascript orientado a objetos, y pese a entender qué es OO, me está costando el tema de los privates, públicos y demás (si alguien conoce una web que sea buena explicándolo lo agradecería, hasta ahora sólo he encontrado jeroglíficos ¬¬)

Problema:
Quiero una clase para controlar los layers de una página; a la izquierda opciones y a la derecha contenido. Al clickear una opción se hace un fadeOut en un layer de la derecha y, al acabar, un fadeIn al que se ha pulsado.
Además, a la opción pulsada le agrego un CSS para indicar que es la activa.

(Advierto de que seguramente es una chapuza...)

Código:

Código:
function faqControl ($firstSelector, $firstLayer) {
// METHODS
	this.switchOption = function ($newSelector, $newLayer) {
		if(this.switchAdmitted()) {
			this.changeLayer($newLayer);			
			this.unselectSelector();
			this.$currentSelector = $newSelector;
			this.selectSelector();
		}		
	};
	
       // Este metodo solo es para asegurarme de que mostramos una capa a la vez.
	this.switchAdmitted = function () {
		if(this.state != 'ready')
		return false;
		else 
		return true;
	}
	this.unselectSelector = function () {
		this.$currentSelector.removeClass('selected');
	};
	
	this.selectSelector = function () {
		this.$currentSelector.addClass('selected');
	};
	
	this.changeLayer = function ($newLayer,callback) {
		this.state = 'changing';
		this.$currentLayer.fadeOut('slow', function () {
			$newLayer.fadeIn('slow', function () {
				this.state='ready';
				});
		});
		this.$currentLayer = $newLayer;
	};
	
	this.showLayer = function () {
		this.$currentLayer.fadeIn('fast');
	};
	
	//Constructor. Given objects will be the first elements shown.
	this.$currentSelector = $firstSelector;
	this.$currentLayer = $firstLayer;
	this.state = 'ready';

	this.selectSelector();
	this.showLayer();
}
Los problemas los tengo en la llamada a funciones desde los callbacks de fadeIn y fadeOut. Creo que tiene algo que ver con los Scopes (áreas de trabajo de las variables, ¿verdad?), y con la forma de declarar variables públicas y privadas. Pero todo esto ahora mismo me es muy confuso porque está muy raramente explicado por ahí fuera.

Gracias por todas las colaboraciones de antemano ;D
  #2 (permalink)  
Antiguo 06/03/2012, 04:02
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: Dudas de novato - Javascript OO

¡buenas!

más o menos hasta donde pude ver, eventualmente el problema es de scope... particularmente sobre el binding en javascript. el binding es el mecanismo que enlaza un identificador con un valor. de lo que conozco, hay dos tipos: early binding y late binding. se refiere en qué punto de la ejecucción se realiza el enlazado. más o menos, el concepto es que en late binding el valor asociado a un identificador se determina en el momento en que se accesa. early binding supongo que es lo contrario. javascript, es de tipo late binding.

el punto es que en el método fadeOut estás pasando una función que utiliza el identificador this en alusión de estar conectado con la instancia de la clase faqControl. cuando esa función literal se invoca, this no esta conectado al objeto que tu esperas, sino al objeto self porque la función literal no tiene "dueño". veamos el siguiente ejemplo. se trata de un objeto que contiene dos métodos: foo, bar. foo recibe un callback y lo invoca, mientras que bar invoca a foo pasando un callback.

Código:
var obj = {
foo: function(callback){ // recibe la funcion y la invoca;
callback();
},

bar: function(){ // invoca foo con un callback;
this.foo(function(){
          console.log(this);
          });
}
};

obj.bar();
nótese en el ejemplo, la función literal (el callback argumentado) se define en el scope de bar. el callback, lo que hace es imprimir en la consola el valor de this. contrario a lo que algunos pensarían, cuando el callback se ejecuta en la consola se imprime un objeto parecido a DOMWindow pese a que this está en el contexto de bar.

¿cómo se soluciona? hay varias técnicas. algunos utilizan el método bind que se encuentra en algunas librerias o en las versiones más recientes de javascript. lo que bind hace es devolver una nueva función que esta enlazada a un objeto. otra alternativa es invocar el método call o apply de las funciones para indicarle sobre cuál objeto debe enlazarse. usando el ejemplo anterior...

Código:
var obj = {
foo: function(callback){
callback.call(this); 
// this aquí hace referencia al objeto que le pertenece el método foo;
},

bar: function(){
this.foo(function(){
          console.log(this);
          });
}
};

obj.bar();
puedes leer más acerca de ello en este artículo, http://www.alistapart.com/articles/g...ingsituations/

edit: me olvide mencionar que en general el concepto de programación orientada a objeto no tiene por que estar relacionado al paradigma de clases. en javascript las clases no existen y por ende el mecanismo de herencia y visibilidad son distintos. es decir, en javascript no se usa las declaraciones public, private o protected porque javascript esta basado en prototipo.

Última edición por zerokilled; 06/03/2012 a las 04:08

Etiquetas: dudas, funcion
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:25.