Javascript: clases con argumentos opcionales

Visita este artí­culo en http://www.estadobeta.com/2006/07/26/javascript-clases-con-argumentos-opcionales/

Por Ismael en Desarrollo, artículos, javascript

Técnicas para crear objetos Javascript con argumentos opcionales.

Como hemos visto aquí en EstadoBeta, una “clase” en Javascript no es más que una función. Para crear una instancia de la clase -un objeto- utilizamos la keyword “new” antes de invocar la función. Dentro de la declaración de la función utilizamos la keyword “this” para asignar o invocar atributos del objeto.


/* declaración de clase "Validador" */
var Validador = function(campo_id){
	this.campo_id = campo_id;
	// haz algo aquí…
}
/* Creación de varias instancias */
var valida_email = new Validador(”email”);
var valida_telefono = new Validador(”telefono”);


Por supuesto estos ejemplos aún no sirven de nada. Para saber cómo agregar y utilizar métodos y atributos a tus clases, lee este otro artículo.

A veces, es necesario pasar argumentos opcionales a tus objetos o funciones. Por ejemplo, nuestra clase Validador podría recibir, además de la id de un input HTML, una lista opcional de criterios de validación, como el máximo de caracteres o una lista de dominios permitidos para los emails.


var Validador = function(campo_id,largo_max,dominios){
	this.campo_id = campo_id;
	this.largo_max = largo_max;
	this.dominios = dominios;
	// haz algo aquí…
}

Pero queremos que esos argumentos sean opcionales. No sólo eso, queremos que, en caso de no ser pasados explícitamente, esos argumentos tengan un valor por default. Si has usado librerías Javascript como la excelente Script.aculo.us, sabrás que estoy hablando de algo como esto:


new Effect.Highlight("titulo",{duration:2,afterfinish:nuevo_efecto});

El primer argumento es la id de un elemento. El segundo es un objeto javascript, escrito en notación literal o jSon.

También conocidos como Hash, estos objetos son básicamente una lista de pares valor/nombre. Una lista de propiedades que podemos pasar a una función como un sólo argumento con múltiples propiedades.


/* Hash de propiedades opcionales. "Dominios" es a su vez un array jSon */
var opciones = {
	largo_max:25,
	dominios:[”hotmail.com”,”gmail.com”]
}
/* Instancia de Validador con objeto de opciones */
var valida_email = new Validador(”email”,opciones);

Ok. Pero ¿cómo usamos esos valores dentro de nuestra clase, y cómo asignamos valores por defecto cuando las opciones no estan presentes?

Primero, debemos ver si la instancia está recibiendo el segundo argumento (opciones). Para eso usamos el array arguments que es creado por Javascript para cada función.


var Validador = function(campo_id){
	this.campo_id = campo_id;
	/* si el segundo argumento no existe, opciones es un objeto vacío. */
	var opciones = arguments[1] || {};
	// haz algo aquí…
}

Una forma elegante y sencilla es usar el operador || para revisar el objeto opciones y sus propiedades.
La línea var opciones = arguments[1] || {}; es lo mismo que


var opciones = {};
if(arguments[1]){
	opciones = arguments[1];
}

Por último, en nuestra clase revisamos una por una las propiedades del objeto opciones y asignamos sus valores al objeto, o un valor por defecto en caso de no existir la opción.


/* declaración de clase "Validador" */
var Validador = function(campo_id){
	this.campo_id = campo_id;
	/* si el segundo argumento no existe, opciones es un objeto vacío. */
	var opciones = arguments[1] || {};
	/* asignamos valores a los atributos de este objeto. */
	this.largo_max = opciones.largo_max	|| 25;//25 es el valor por default
	this.largo_min = opciones.largo_min	|| 10;
	this.dominios = opciones.dominios	|| [”hotmail.com”,”yahoo.com”,”esfera.cl”];
	// haz algo aquí…
}
/* Creación de varias instancias */
var valida_email	= new Validador(”email”,{largo_max:40,dominios:[”hotmail.com”,”gmail.com”]});
var valida_telefono	= new Validador(”telefono”,{largo_max:9,largo_min:7});

7 comentarios para “Javascript: clases con argumentos opcionales”

  1. GravatarEstadoBeta » Archivo » Prototype Dice:

    […] Y eso es lo básico de Ajax. El tercer argumento de Ajax.Updater es un objeto de parámetros opcionales. Ahí es posible definir callbacks o funciones que se ejecutarán según la petición Ajax termine con exito o fracase. […]

  2. Gravatarcoto Dice:

    Ismael.

    Haciendo un pequeño resumen, si un objeto se puede escribir en javascript del modo


    var obj = new Object();
    obj.nombre = "juan"; // atributo o propiedad.
    obj.getNombre = function(){ //metodo
        return this.nombre;
    }

    o bien a através de un hash, como haces mención en otro artículo


    var obj = {
      nombre: "Juan",
      getNombre: function(){
        return this.nombre;
      }
    }

    luego, estamos de acuerdo que cuando una variable es de tipo “function” sería una clase y luego un objeto sería una instanciación a dicha clase (tal como mencionas en las primeras lineas de este mismo artículo), mi pregunta es la siguiente, ¿en que casos es más útil cada uno de los tres tipos de objetos vistos?
    ¿hay alguna ventaja de usar new Object por ejemplo?

  3. GravatarIsmael Dice:

    Buena pregunta Coto (y gracias por el clarísimo resumen!).
    Supongo que es cuestión de preferencias, pero la sintáxis jSon, una vez te acostumbras, puede ser algo más sintética y homogenea, especialmente si usas librerías como Prototype o Scriptaculous que están escritas en ese estilo.
    Hay que tener en cuenta que tus dos ejemplos definen una instancia de Object y no una “clase”. El método getNombre() está siendo definido directamente sobre una instancia. Para crear una clase y definir métodos que estarán disponibles para todas las instancias:

    
    // Clase y métodos
    var Persona = new Function(nombre){
        this.nombre = nombre;
    }
    Persona.prototype.getNombre = function(){
        return this.nombre;
    }
    // Instancias
    var obj1 = new Persona("Coto");
    var obj2 = new Persona("Ismael");
    
    var un_nombre = obj1.getNombre(); //"Coto"
    
    

    Más info en esta nota.

  4. Gravatarcoto Dice:

    Gracias Man !!

  5. Gravatarrockerox Dice:

    var Validador = function(campo_id,largo_max,dominios){
    this.campo_id = campo_id;
    this.largo_max = largo_max || 10 ;
    this.dominios = dominios || 0;
    }

    Será Algo así lo que buscas ???

  6. GravatarIsmael Dice:

    Rockerox: la diferencia de mi ejemplo es que puedes pasar un hash de argumentos opcionales.

    a = new Validador('email', {dominios:2});
    

    En tu ejemplo, si sólo quieres pasar “dominios” estas obligado también a pasar explícitamente “largo_max”.

  7. Gravatarzancom Dice:

    Buenas tardes, estoy estudiando a fondo el javascript y encontre una libreria que puedo usar en un proyecto, pero estoy confundido, aqui les envio una parte a ver si me pueden ayudar.

    var dibujar=new Object();

    dibujar.evento=function(){this.tipo=null,this.valor=null};
    dibujar.evento.prototype.initEvent=function(sType,_591e){instrucciones}

    primera pregunta: como deduzco yo que dibujar.evento es una subclase de dibujar y no un metodo, sera porque luego tiene opciones de prototype.

    dibujar.mover=function(){instrucciones}
    dibujar.mover.prototype= new dibujar.event;

    segunda pregunta: podria decir tambien dibujar.mover.prototype=new dibujar.event(); cual es la diferencia?

    var mover = new dibujar.mover();

    tercera pregunta: podria explicarme el significado de esta instruccion y la diferencia con la instruccion anterior

    gracias de antemano.

Deja un comentario

XHTML: puedes usar estas etiquetas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>