Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Tips de Javascript: Creación de objetos

Javascript es un lenguaje orientado a objetos, en teoría, pero tiene una particularidad interesante, no posee clases, con lo cual la creación de objetos se hace de otras manera que como haríamos en C#.

Formas de crear objetos número uno, literal:

La notación literal es la más común y permite declarar un objeto a partir de una expresión JSON, por ejemplo de este modo

var persona = {};
persona.nombre = 'leonardo';

console.log(persona.nombre);

image

Esto nos lleva a dos conclusiones:

  • Primero podemos crear objetos sin la existencia de una clase.

  • Segunda los objetos que creamos son mutales, notemos que hemos agregado la propiedad nombre luego de la declaración del objeto, interesante.

Es posible en la misma declaración incluir las propiedades y funciones, del siguiente modo:

var persona = {
				nombre:'leonardo' , 
				saludar:function(){ 
					return 'hola mi nombre es ' + this.nombre;}
			   };
			   
console.log(persona.saludar());

image

perfecto, es claro que  podemos declarar tanto propiedades como funciones de un objeto con una expresión literal, un JSON, nuestros objetos serán mutales y se podrán agregar más miembros en cualquier momento.

Creación de objetos a partir de funciones, forma dos:

Una forma más natural (para los que venimos de C#) de crear objetos en javascript es a partir de una función constructor, el ejemplo anterior utilizando esta técnica sería así:

Persona = function (nombre){
			this.nombre = nombre;
			this.saludar = function()
			{
				return "hola mi nombre es " + this.nombre;
			}
	};
			   
var persona = new Persona('Leonardo');
			   
console.log(persona.saludar());

y obtenemos el mismo resultado, la ventaja de esta forma es que podemos crear muchos objetos iguales, por ejemplo así:

Persona = function (nombre){
			this.nombre = nombre;
			this.saludar = function()
			{
				return 'hola mi nombre es ' + this.nombre;
			}
	};
			   
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
			   
console.log(leonardo.saludar());			   
console.log(gabriel.saludar());

y todo funciona muy bien, ahora vamos a ver un poco qué pasa en el DOM

image

Vemos algo interesante:  tanto la propiedad “nombre” como la función “saludar” se encuentran a nivel objeto y no a nivel función “Persona”, lo que significa que se crea una nueva copia de la propiedad y de la función para cada uno de los objetos que generemos a parir de la función, en principio es poco deseable.

Utilizando prototipos

La forma de tener miembros reutilizables es agregarlos al prototipo, del siguiente modo:

Persona = function (nombre){
			this.nombre = nombre;
			Persona.prototype.saludar = function()
			{
				return 'hola mi nombre es ' + this.nombre;
			}
	};
			   
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
			   
console.log(leonardo.saludar());			   
console.log(gabriel.saludar());

image

ahora si, vemos que la función saludar pertenece al prototipo (__proto__) al igual que la función constructor, lo cual implica que ambos objetos utilizan la misma copia de la función, mucho mejor.

Variables estáticas?

Algo así, la pregunta es: qué pasa si ponemos también la propiedad nombre a nivel prototipo?

Persona = function (nombre){
			Persona.prototype.nombre = nombre;
			Persona.prototype.saludar = function()
			{
				return 'hola mi nombre es ' + this.nombre;
			}
	};
			   
var leonardo = new Persona('leonardo');
var gabriel = new Persona('gabriel');
			   
console.log(leonardo.saludar());			   
console.log(gabriel.saludar());

image 

Vemos que tanto __proto__ como los dos objetos tienen el mismo valor en la propiedad “nombre” es porque al se una propiedad dentro del prototipo es siempre la misma, con lo cual va a tomar el valor que se le asignó en última instancia para todos los objetos y el prototipo, en este caso “gabriel”

Hasta la próxima.

2011-11-26 EDIT: como me comenta Carlos por mensaje privado, no es correcto acceder al prototipo en la función constructor ya que se ejecutaría con cada nuevo objeto, en contra de la idea final que es usar la misma instancia de la función, el código correcto debería modificar el prototipo por fuera de la función constructor, de la siguiente manera:

Persona = function (nombre){
			this.nombre = nombre;
	};
Persona.prototype.saludar = function(){
	return 'hola mi nombre es ' + this.nombre;
}

Gracias Carlos!

Tips de Javascript: parseInt

Muchas veces nos encontramos con la necesidad de convertir un valor que inicialmente es texto en un entero, entonces rápidamente se nos ocurre ir a buscar la función parseInt de javascript, bien, existe un detalle muy interesante acerca del comportamiento de la misma, veámos un ejemplo.

var valor = "10";
var numero = parseInt(valor); 
console.log(numero);

image

(con F12 activamos el IE Develpoer Toolbar que nos permite tener acceso al objeto console)

Esto está muy bien, es el resultado esperado, pero qué pasa si hacemos lo siguiente.

var valor = "010";
var numero = parseInt(valor); 
console.log(numero);

image

chan!! nos da 8.

parseInt infiere que el valor que ingresamos está en base octal, y resulta que 10 en octal es 8 la forma correcta de evitar esto es siempre indicar la base como segundo parámetro de la función parseInt como se indica en la documentación de Mozilla.

var valor = "010";
var numero = parseInt(valor, 10); 
console.log(numero);

image

y problema solucionado, hasta la próxima.

QUnit pruebas unitarias en javascript

A medida que las aplicaciones son cada vez más “web 2” con Ajax y todas esas cosas nos encontramos con código javascript que necesitamos probar ya que toma cada vez más relevancia en nuestro negocio.

QUnit

QUnit es un framework de unit testing para javascript como otros, pero tiene una particularidad: es el utilizado en el core de jQuery por lo tanto parece natural usarlo si éste es nuestro framework de javascript preferido.

Manos a la obra

Para utilizar QUnit no necesitamos mucho, dos cosas en realidad, un archivo js con todo el código y una hoja de estilos, podemos encontrar el enlace para descargar ambos acá

Vamos a hacer un ejemplo paso a paso al estilo TDD porque antes que nada somos hombres

Configurando para usar QUnit

Bien, antes que nada tenemos que armar una página para contener los test, es necesario contar con algunos elementos en la misma para que QUnit pueda mostrarnos los resultados y demás y una hoja de estilos que viene incluída, entonces nuestra página inicial sería así:

<html>
<head><title>Test números complejos</title>
<link rel="stylesheet" href="js/qunit.css" type="text/css" media="screen">
<script src="js/qunit.js" type="text/javascript" /></script>
<script type="text/javascript" >

</script>
</head>
<body>
	<h1 id="qunit-header">Test Suite</h1>
	<h2 id="qunit-banner"></h2>
	<div id="qunit-testrunner-toolbar"></div>
	<h2 id="qunit-userAgent"></h2>
	<ol id="qunit-tests"></ol>
	<div id="qunit-fixture">test markup</div>
<body>
</html>

Ahora empecemos con lo entretenidos, plantenado nuestro primer test

Primer test sumar dos números

Para indicar que vamos a hacer un test usamos la función test() de QUnit la misma recibe dos parámetros

  • El nombre del test
  • La función que se ejecuta cuando se corre el test

Por ejemplo

test("sumar", function()
{
	//configuraciones
	//ejecución
	//verificaciones
}

Lo interesante de hacer TDD es que vamos a escribir lo que queremos que pase antes de que exista, es decir, primero invocamos a los métodos y escribimos el resultado esperado antes de implementar el código, en el caso de la suma sería así:

<html>
<head><title>Test números complejos</title>
<link rel="stylesheet" href="js/qunit.css" type="text/css" media="screen">
<script src="js/qunit.js" type="text/javascript" /></script>
<script type="text/javascript" >
test("sumar", function()
{
	var a = 1;
	var b = 4;
	var r = Sumar(a,b);
	equal(r,5);
});

</script>
</head>
<body>
	<h1 id="qunit-header">Test Suite</h1>
	<h2 id="qunit-banner"></h2>
	<div id="qunit-testrunner-toolbar"></div>
	<h2 id="qunit-userAgent"></h2>
	<ol id="qunit-tests"></ol>
	<div id="qunit-fixture">test markup</div>
<body>
</html>

Abrimos la página con el navegador y vemos que el test falla porque no existe la función Sumar

image

Entonces vamos a implementarla, avanzando con pasos pequeños primero simplemente la definimos pero no hacemos que cumpla su funcionalidad

test("sumar", function()
{
	var a = 1;
	var b = 4;
	var r = Sumar(a,b);
	equal(r,5);
});

function Sumar(a,b)
{
	return 0;
}

Corremos nuevamente el test y falla nuevamente pero esta vez porque el resultado no es el esperado

image

Como vemos qUnit nos indica que el resultado obtenido es diferente al esperado, entonces implementamos el código correcto

function Sumar(a,b)
{
	return a + b;
}

image

Y listo, tenemos implementado el código correcto con un bonito test que lo verifica.

La idea detrás de todo esto

La idea de hacer TDD es descubrir el diseño a partir del uso ya que plantear las pruebas nos permite “usar” el código y de esta manera logramos lo siguiente:

  • Diseño emergente a partir del uso.
  • Nos hacemos un grupo de pruebas que podemos volver a correr luego, cuando agreguemos funcionalidad o cuando mejoremos el código
  • Sirve como ejemplo de utilización del código
  • Entonces si podemos automatizar el grupo de test para ejecutarlo durante un build la felicidad está a un paso..o casi.

El video

Por último dejo un ejemplo más complejo en un video con varios test y refactor. Hasta la próxima.

Leonardo.

Seminario sobre jQuery en el MUG

UPDATE 2011.09.27
Están disponibles los ejemplos que desarrollamos durante la charla acá
Y para verlos on-line desde acá

Finalmente el primer post en este nuevo blog es también una excelente noticia, después de casi un año y medio vuelvo a dar una charla en el Grupo de Usuarios de Microsoft de Argentina (MUG), en este caso será sobre nuestro framework de javascript favorito jQuery. La idea es presentarlo para los que escuchan por todos lados y nunca lo usaron todavía y para los que recién empiezan repasar y ver nuevas cosas.

Costo, lugar, fecha y hora.

La charla es totalmente gratuita, el lugar será en el Auditorio del MUG - Rivadavia 1479 1º A - Capital Federal.

La fecha es el lunes 26 de septiembre a partir de las 18:30hs hasta las 21:30hs.

image

Temario

El temario de la charla es el siguiente:

-HTML y DOM.
-Introducción a jQuery, filosofía, compatibilidad, separación de conceptos.
-Selectores, sintáxis, agrupamiento.
-Atributos, filtros, modificación.
-Manipulación, creación de elementos dinámicamente, edición.
-Eventos, asociación dinámica de eventos.
-Efectos.
-Ajax, llamadas Ajax, manipulación del objeto XMLHTTPRequest.
-Utilidades, serialización, plugins.
-Integración con ASP.NET MVC y Ajax, carga dinámica de elementos.
-jQuery UI.

Vamos charlar más o menos sobre los temas en función de el feedback que haya, por ejemplo al principio incluí HTML y DOM como un concepto de base que es indispensable, es esperable que todos los conozcan y en todo caso será cosa de un minuto, sino nos tomaremos 10 o los que sena necesarios.

La idea es al final comprender bien qué nos aporta el framework y sus ventajas, también qué es Ajax y cómo se facilita con jQuery.

Ejemplos y más ejemplo.

Por supuesto como hago siempre, vamos a ir desarrollando los ejemplos en el momento a partir de una idea y en caso de alguna duda puntual intentaremos resolverla.

Los espero. Leonardo.

Link de la charla; http://www.mug.org.ar/Eventos/3675.aspx
Registración http://www.mug.org.ar/registracion.aspx?idevento=3675