viernes, 2 de junio de 2017

Javascript Parte XLVI

Como los Array en Javascript son objetos, los mismos tienen una serie de métodos que nos facilitan trabajar con ellos.
Para insertar elementos en un vector hemos visto que con solo asignar un valor al vector en un determinado índice el dato queda almacenado y eventualmente el atributo length modificado:
  var vec=[];
  vec[0]=10;
  vec[1]=20;  
  document.write(vec.length);  //imprime 2
Esta sintaxis tenemos que tener cuidado como variamos el subíndice para no dejar componentes vacías si queremos implementar un array denso.
Una variante para resolver este mismo problema es utilizar el método push del objeto Array. Este método añade el valor al final del vector:
  var vec=[];
  vec.push(10);
  vec.push(20);  
  document.write(vec.length);  //imprime 2
Automáticamente cuando llamamos al método push el valor que le pasamos en el parámetro se almacena en el vector y se incrementa el atributo length.
Podemos inclusive llamar al método push pasando más de 1 parámetro:
  var vec=[];
  vec.push(10,20);
  document.write(vec.length);  //imprime 2
El método inverso llamado pop extrae el último elemento del Array y decrementa en uno el atributo length:
  var vec=[];
  vec.push(10,20,30,40);  
  document.write(vec.length+'<br>');  //imprime 4
  vec.pop();
  document.write(vec.length+'<br>');  //imprime 3
  document.write(vec.pop()+'<br>');   //imprime un 30
  document.write(vec.length+'<br>');  //imprime 2
El método pop() además de eliminar el último elemento del vector retorna el valor almacenado en dicha componente.
Si llamamos al método pop y el vector está vacío retorna el valor undefined.
Problema
Realizar la carga de sueldos por teclado hasta que se ingrese el cero. Almacenar todos los valores ingresados en un vector empleando el método push. Mostrar la suma de sueldos ingresados.
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var sueldos=[];
  var monto;
  do {
    monto=prompt('Ingrese el sueldo (0 para finalizar):','');
    monto=parseInt(monto);
    if (monto!=0)
    {
      sueldos.push(monto);
    }
  } while (monto!=0);
  var suma=0;
  for(var f=0;f<sueldos.length;f++)
  {
    suma=suma+sueldos[f];
  }
  document.write('El total en sueldos ingresado es:'+suma);

</script>

</body>
</html>
De esta forma no llevamos un contador para indicar la posición donde se debe almacenar la componente en el vector:
      sueldos.push(monto);

Javascript Parte XLV

Hasta ahora siempre que inicializamos los array no dejamos espacios sin utilizar. Javascript permite crear array e inicializar componentes no contiguas.
Por ejemplo podemos crear un vector e inicializar las componentes con subíndice 5 y 10:
  var vec=[];
  vec[5]=100;
  vec[10]=200;
Este tipo de array se los llama array dispersos ya que no tenemos todas las componentes contiguas ocupadas. Veamos con un ejemplo que pasa con la propiedad length y cuando accedemos a componentes que no existen en el vector:
<html>
<head>
</head>
<body>

<script type="text/javascript">
    
  var vec=[];
  vec[5]=100;
  vec[10]=200;
  document.write('Atributo length:'+vec.length+'<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
Si ejecutamos este programa la salida en la página será:
Atributo length:11
undefined
undefined
undefined
undefined
undefined
100
undefined
undefined
undefined
undefined
200
Como podemos ver el atributo length almacena teniendo en cuenta la posición más grande asignada (en nuestro ejemplo vec[10])
Por otro lado cuando accedemos a componentes no inicializadas obtenemos el valor "undefined".
Es bueno tener en cuenta que las componentes no inicializadas no reservan espacio en memoria, luego si asignamos como subíndice el dni de una persona:
  dni[20438470]=100;
no significa que se reservan más de veinte millones de componentes para los otros elementos del vector. La reserva de espacio sucede a medida que ocupamos espacios del vector.
Problema
Ingresar por teclado un nro de cliente y el monto a depositar. Almacenar en un vector, utilizar como subíndice el nro de cliente y almacenar el monto depositado. Sumar todos los depósitos recorriendo el vector e identificando las componentes cargadas (es decir las que tienen un valor distinto a null). Imprimir la suma total depositada y la cantidad de clientes que depositaron.
<html>
<head>
</head>
<body>

<script type="text/javascript">
  var depositos=[];
  var nro,monto;
  do {
    nro=prompt('Ingrese nro de cliente','');
    nro=parseInt(nro);
    if (nro!=0)
    {
      monto=prompt('Ingrese monto a depositar','');
      monto=parseInt(monto);
      depositos[nro]=monto;
    }
  } while (nro!=0);
  var suma=0;
  var canti=0;
  for(var f=0;f<depositos.length;f++)
  {
    if (depositos[f]!==undefined)
    {
      suma=suma+depositos[f];
      canti++;
    }
  }
  document.write('Cantidad de depósitos:'+canti+'<br>');
  document.write('Total depositado por todos los clientes:'+suma);
</script>

</body>
</html>
Como vemos el do/while finaliza cuando ingresamos un 0, cuando ingresamos en la variable nro un valor distinto a cero procedemos a almacenar en el vector en la posición indicada por nro el valor cargado en monto:
  do {
    nro=prompt('Ingrese nro de cliente','');
    nro=parseInt(nro);
    if (nro!=0)
    {
      monto=prompt('Ingrese monto a depositar','');
      monto=parseInt(monto);
      depositos[nro]=monto;
    }
  } while (nro!=0);
Cuando sale del do/while mediante un ciclo for analizamos cada una de las componentes posibles del vector verificando si el valor es distinto a undefined (es importante notar que debemos utilizar el operador relacionar !== en lugar de != ya que no funcionaría cuando una componente almacene null):
  for(var f=0;f<depositos.length;f++)
  {
    if (depositos[f]!==undefined)
    {
      suma=suma+depositos[f];
      canti++;
    }
  }

Javascript Parte XLIV

Todos los vectores donde almacenamos en forma contigua todos sus elementos son llamados array densos.
Almacenar elementos siguiendo esta premisa tiene como ventaja poder acceder a sus elementos mediante una estructura repetitiva disponiendo el contador del for como subíndice.
Una propiedad de suma utilidad trabajando los vectores sin dejar subíndices sin utilizar es la propiedad length. La propiedad length almacena la cantidad de componentes que tiene el vector.
Problema
Crear un vector vacío. Mediante una estructura repetitiva solicitar la carga de elementos por teclado hasta que se ingrese el cero. No almacenar dicho valor en el vector. Luego sumar todas las componentes del vector, mostrar dicha suma y el tamaño del vector.
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[];
  var valor;
  var indice=0;
  do {
    valor=prompt('Ingrese un valor entero (0 para finalizar)','');
    valor=parseInt(valor);
    if (valor!=0)
    {
      vec[indice]=valor;
      indice++;
    }
  } while (valor!=0);
  var f;
  var suma=0;
  for(f=0;f<vec.length;f++)
  {
    suma=suma+vec[f];
  }
  document.write('Se ingresaron '+vec.length+' valores<br>');
  document.write('La suma de los valores ingresados es:'+suma);

</script>

</body>
</html>
Definimos un vector vacío:
  var vec=[];
Creamos una estructura repetitiva do/while que se ejecutará hasta que ingresemos en la variable valor el cero:
  do {
    valor=prompt('Ingrese un valor entero (0 para finalizar)','');
    valor=parseInt(valor);
    if (valor!=0)
    {
      vec[indice]=valor;
      indice++;
    }
  } while (valor!=0);
Cada vez que se ingresa un valor distinto a cero se lo asignamos a una componente del vector y para que ocupen posiciones consecutivas definimos un contador llamado indice que se inicializa en cero previo a la estructura repetitiva:
    if (valor!=0)
    {
      vec[indice]=valor;
      indice++;
    }
Cuando salimos del do/while mostramos el atributo length del vector y sumamos sus componentes para mostrar dicho acumulador.

Javascript Parte XLIII

Como hemos visto un array o arreglo es una estructura de datos que permite almacenar elementos y luego acceder a los mismos por medio de subíndices.
Recordemos que Javascript administra los array mediante un objeto especializado llamado Array.
Un array puede almacenar en sus componentes elementos de datos distintos y su tamaño puede crecer a lo largo de la ejecución del programa.
Tenemos muchas formas de inicializar un array en Javascript según nuestra situación particular, veamos con ejemplos diferentes formas:
Creación de un array sin elementos:
  var vector1=new Array();
Otra sintaxis para crear un array sin elementos:
  var vector2=[];
Creación de un array indicando la cantidad de componentes iniciales que podrá almacenar:
  var vector3=new Array(5);
Creación e inicialización llamando al constructor Array y pasando como parámetros los valores a almacenar en las componentes:
  var vector4=new Array(1,70,'juan');  
Creación e inicialización de un array utilizando los corchetes:
  var vector5=[1,70,'juan'];  
Para probar las distintas formas de creación de array implementaremos un programa que cree 5 Array, cargue algunos elementos y muestre la primer componente de cada uno de ellos:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vector1=new Array();
  vector1[0]=1;

  var vector2=[];
  vector2[0]=1;

  var vector3=new Array(5);
  vector3[0]=1;

  var vector4=new Array(1,70,'juan');  
  var vector5=[1,70,'juan'];  

  document.write(vector1[0]+'<br>');
  document.write(vector2[0]+'<br>');
  document.write(vector3[0]+'<br>');
  document.write(vector4[0]+'<br>');
  document.write(vector5[0]+'<br>');

</script>

</body>
</html>

Javascript Parte XLII

Veremos ahora otra forma muy utilizada en Javascript para definir objetos. Esta forma se la llama Objetos literales
Esta metodología consiste en definir una lista de propiedades y sus valores. Veamos con un ejemplo esta técnica:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var cliente1= {
     nombre: 'Juan',
     deposito: 0,
     imprimir: function ()
     {
       document.write(this.nombre+'<br>');
       document.write(this.deposito+'<br>');
     },
     depositar: function(monto) {
       this.deposito=this.deposito+monto;
     },
     extraer: function(monto) {
       this.deposito=this.deposito-monto;
     }                  
  };

  cliente1.imprimir();
  cliente1.depositar(1000);
  document.write('Estado luego de depositar 1000 pesos</br>');
  cliente1.imprimir();
  cliente1.extraer(200);
  document.write('Estado luego de extraer 200 pesos</br>');
  cliente1.imprimir();

</script>

</body>
</html>
En este ejemplo hemos creado un objeto literal llamado cliente1, la sintaxis mínima para crear un objeto vacío sería:
  var cliente1= {};
Es decir creamos una variable llamada cliente1 y le asignamos un bloque encerrado entre llaves vacío. Es importante notar el punto y coma al final de la llave de cerrado (como ocurre cuando asignamos un valor a una variable)
Veamos ahora si decimos que el objeto cliente1 define la propiedad nombre, luego nuestro objeto quedará definido con la sintaxis:
  var cliente1= {
     nombre: 'Juan'
  };
Decimos que la propiedad nombre almacena el string 'Juan', del lado izquierdo indicamos el nombre de la propiedad y del lado derecho de los dos puntos indicamos el valor de la propiedad del objeto (el valor puede ser de cualquier tipo, en este caso es de tipo string pero podría ser de tipo number, boolean, object, Array etc.)
Ahora si agregamos una segunda propiedad a nuestro objeto cliente1 llamada deposito (que representa la cantidad de dinero que tiene depositado el cliente1) la sintaxis queda:
  var cliente1= {
     nombre: 'Juan',
     deposito: 0
  };
Como podemos observar separamos por coma cada inicialización de propiedad del objeto (menos para la última propiedad donde aparece la "}".
Las funciones del objeto también definimos una sintaxis similar a la declaración de sus propiedades:
  var cliente1= {
     nombre: 'Juan',
     deposito: 0,
     imprimir: function ()
     {
       document.write(this.nombre+'<br>');
       document.write(this.deposito+'<br>');
     },
     depositar: function(monto) {
       this.deposito=this.deposito+monto;
     },
     extraer: function(monto) {
       this.deposito=this.deposito-monto;
     }                  
  };
Del lado izquierdo de los dos puntos indicamos el nombre de la función y del lado derecho utilizamos la palabra clave function junto con los parámetros.
En la función podemos acceder a las propiedades del objeto antecediendo la palabra clave this.
Ahora solo nos falta hacer la llamada a las funciones del objeto cliente1:
  cliente1.imprimir();
  cliente1.depositar(1000);
  document.write('Estado luego de depositar 1000 pesos</br>');
  cliente1.imprimir();
  cliente1.extraer(200);
  document.write('Estado luego de extraer 200 pesos</br>');
  cliente1.imprimir();

martes, 9 de mayo de 2017

Javascript Parte XLI

Podemos crear vectores con componente de tipo objeto.
Con un ejemplo veremos la sintaxis para trabajar con los mismos. Desarrollaremos una clase que represente un hipervínculo y luego definiremos un vector con componentes de tipo hipervinculo.
La clase hipervínculo es:
<script type="text/javascript">
  function Hipervinculo(direccion,titulo)
  {
    this.direccion=direccion;
    this.titulo=titulo;
    this.retornarhipervinculo=retornarhipervinculo;
  }

  function retornarhipervinculo()
  {
    var cadena;
    cadena='<a href=' + this.direccion + '>' + this.titulo + '</a>';
    return cadena;
  }
</script>

Luego el bloque donde se usa la clase Hipervínculo es:
<script type="text/javascript">
  var vector=new Array(3);
  vector[0]=new Hipervinculo('http://www.google.com','google');
  vector[1]=new Hipervinculo('http://www.msn.com','msn');
  vector[2]=new Hipervinculo('http://www.yahoo.com','yahoo');
  for(var f=0;f<vector.length;f++)
  {
    document.write(vector[f].retornarhipervinculo());
    document.write('<br>');
  }
</script>
Creamos un objeto de la clase Array y luego guardamos en cada componente un objeto de la clase hipervínculo (pasándole como parámetros al constructor, la dirección del sitio y el texto a mostrar en la página. Luego recorremos con un 'for' las componentes del vector e imprimimos en la página cada hipervínculo.

Javascript Parte XL

En JavaScript podemos definir varias clases en un mismo programa.
Vamos a desarrollar un programa que contenga dos clases. Plantearemos una clase Numeroquiniela que representa una persona que elige un número de quiniela y además registra su nombre, la clase tiene por objetivo la carga por el teclado del número deseado.
Por otra parte crearemos una clase Bolillero que sortee un valor aleatorio entre 1 y 10 (que representa el valor extraído del bolillero).
La codificación de las dos clases es:
<html>
<head>
<title>Problema</title>
<script type="text/javascript">

  //clase Numeroquiniela ************************************************
  function Numeroquiniela(nombre)
  {
    this.nombre=nombre;
    this.cargarnumero=cargarnumero;
    this.verificarsigano=verificarsigano;
  }

  function cargarnumero()
  {
    this.numero=prompt("Que número de quiniela quiere?","");
  }

  function verificarsigano(num)
  {
    if (this.numero==num)
      return true;
    else
      return false;
  }

  //clase Bolillero ************************************************
  function Bolillero()
  {
    this.numero=-1;
    this.sortear=sortear;
  }
  
  function sortear()
  {
    this.numero=parseInt(Math.random()*10)+1;
  }

</script>
</head>
<body>

<script type="text/javascript">
  var numeroquiniela1;
  numeroquiniela1=new Numeroquiniela("juan");
  numeroquiniela1.cargarnumero();
  var numeroquiniela2;
  numeroquiniela2=new Numeroquiniela("ana");
  numeroquiniela2.cargarnumero();
  var bolillero;
  bolillero=new Bolillero();
  bolillero.sortear();
  document.write('Numero sorteado:' + bolillero.numero + '<br>');
  document.write(numeroquiniela1.nombre + ' eligió ' + numeroquiniela1.numero +'<br>');
  document.write(numeroquiniela2.nombre + ' eligió ' + numeroquiniela2.numero +'<br>');
  if (numeroquiniela1.verificarsigano(bolillero.numero))
  {
    document.write(numeroquiniela1.nombre + ' a ganado <br>');
  }
  if (numeroquiniela2.verificarsigano(bolillero.numero))
  {
    document.write(numeroquiniela2.nombre + ' a ganado <br>');
  }
</script>
</body>
</html>
Al constructor de la clase Numeroquiniela llega como parámetro el nombre de la persona que la compra (podíamos cargarlo por teclado al nombre también).
Al número que selecciona lo cargamos por teclado. La clase Numeroquiniela además tiene otra responsabilidad, que es avisarnos si a ganado según el número sorteado.
Por otro lado en la página html definimos dos objetos de la clase Numeroquiniela y uno de la clase Bolillero:

Javascript Parte XXXIX

El lenguaje JavaScript no es un lenguaje orientado a objetos completo, pero permite definir clases con sus atributos y responsabilidades. Finalmente nos permite definir objetos de estas clases.
Pero el otro pilar de la programación orientada a objetos, es decir la herencia, no está implementada en el lenguaje.
Veremos la sintaxis para la declaración de una clase y la posterior definición de objetos de la misma.

Desarrollaremos una clase que represente un cliente de un banco.
La clase cliente tiene como atributos:
nombre
saldo
y las responsabilidades o métodos de la clase son:
Constructor (inicializamos los atributos del objeto)
depositar
extraer
Luego debemos implementar los siguientes métodos (normalmente el constructor se utiliza el caracter mayúscula):
function Cliente(nombre,saldo)
{
  this.nombre=nombre;
  this.saldo=saldo;
  this.depositar=depositar;
  this.extraer=extraer;
}

function depositar(dinero)
{
  this.saldo=this.saldo+dinero;
}

function extraer(dinero)
{
  this.saldo=this.saldo-dinero;
}
El nombre de la clase coincide con el nombre de la función principal que implementamos (también llamado constructor de la clase):
function cliente(nombre,saldo)
{
  this.nombre=nombre;
  this.saldo=saldo;
  this.depositar=depositar;
  this.extraer=extraer;
}
A esta función llegan como parámetro los valores con que queremos inicializar los atributos. Con la palabra clave 'this' diferenciamos los atributos de los parámetros (los atributos deben llevar la palabra clave this)
  this.nombre=nombre;
  this.saldo=saldo;
También en el constructor inicializamos la referencia a todos los métodos que contendrá la clase (esto es muy importante y necesario para entender porque las otras dos funciones pertenecen a esta clase):
  this.depositar=depositar;
  this.extraer=extraer;
Por último, implementamos todos los métodos de la clase:
function depositar(dinero)
{
  this.saldo=this.saldo+dinero;
}

function extraer(dinero)
{
  this.saldo=this.saldo-dinero;
}
De nuevo recordemos que diferenciamos los atributos de la clase por la palabra clave this.

Ahora veamos el archivo HTML completo donde además definiremos un objeto de la clase planteada:
<html>
<head>
<title>Problema</title>

<script type="text/javascript">
  function Cliente(nombre,saldo)
  {
    this.nombre=nombre;
    this.saldo=saldo;
    this.depositar=depositar;
    this.extraer=extraer;
  }

  function depositar(dinero)
  {
    this.saldo=this.saldo+dinero;
  }

  function extraer(dinero)
  {
    this.saldo=this.saldo-dinero;
  }

</script>

</head>
<body>

<script type="text/javascript">
  var cliente1;
  cliente1=new Cliente('diego',1200);
  document.write('Nombre del cliente:'+cliente1.nombre+'<br>');
  document.write('Saldo actual:'+cliente1.saldo+'<br>');
  cliente1.depositar(120);
  document.write('Saldo luego de depositar $120---->'+cliente1.saldo+'<br>');
  cliente1.extraer(1000);
  document.write('Saldo luego de extraer $1000---->'+cliente1.saldo+'<br>'); 
</script>

</body>
</html>
Hemos dividido la declaración de la clase en un bloque Javascript distinto a donde definimos un objeto de la misma, esto no es obligatorio, pero podemos ver que queda más claro.
Para definir un objeto de la clase Cliente tenemos:
  var cliente1;
  cliente1=new Cliente('diego',1200);
Luego las llamadas a métodos le antecedemos el nombre del objeto llamado cliente1:
  document.write('Nombre del cliente:'+cliente1.nombre+'<br>');
  document.write('Saldo actual:'+cliente1.saldo+'<br>');
  cliente1.depositar(120);
  document.write('Saldo luego de depositar $120---->'+cliente1.saldo+'<br>');
  cliente1.extraer(1000);
  document.write('Saldo luego de extraer $1000---->'+cliente1.saldo+'<br>'); 
Podemos decir que la ventaja que podemos obtener con el planteo de clases es hacer nuestros programas mucho más organizados, entendibles y fundamentalmente, poder reutilizar clases en distintos proyectos.

Javascript Parte XXXVIII

El lenguaje JavaScript permite agrupar funciones y disponerlas en un archivo separado a la página HTML.
Esto trae muchos beneficios:
- Reutilización de funciones en muchos archivos. No tenemos que copiar y pegar sucesivamente las funciones en las páginas en las que necesitamos.
- Facilita el mantenimiento de las funciones al encontrarse en archivos separados.
- Nos obliga a ser más ordenados.

La mecánica para implementar estos archivos externos en JavaScript es:
1 - Crear un archivo con extensión *.js y tipear las funciones en la misma:
function retornarFecha()
{
  var fecha
  fecha=new Date();
  var cadena=fecha.getDate()+'/'+(fecha.getMonth()+1)+'/'+fecha.getYear();
  return cadena;
}

function retornarHora()
{
  var fecha
  fecha=new Date();
  var cadena=fecha.getHours()+':'+fecha.getMinutes()+':'+fecha.getSeconds();
  return cadena; 
}
2 - Creamos un archivo html que utilizará las funciones contenidas en el archivo *.js:
<html>
<head>
<title>Problema</title>
<script type="text/javascript" src="funciones.js"></script>
</head>
<body>

<script type="text/javascript">
  document.write('La fecha de hoy es:'+retornarFecha());
  document.write('<br>');
  document.write('La hora es:'+retornarHora());
</script>

</body>
</html>
Es decir debemos disponer el siguiente código para importar el archivo *.js:
<script type="text/javascript" src="funciones.js"></script>
Mediante la propiedad src indicamos el nombre del archivo a importar.
Luego, podemos llamar dentro de la página HTML, a las funciones que contiene el archivo externo *.js; en nuestro ejemplo llamamos a las funciones retornarFecha() y retornarHora().
Como podemos ver, el archivo html queda mucho más limpio.
Si quiere probar en su equipo este ejemplo puede descargar el editor de texto NotePad++.

Tipear los dos archivos y los almacenamos en una carpeta del disco duro:
funciones.js
editor NotePad++
y la página html (pagina1.html):
editor NotePad++
Procedemos a abrir desde el navegador el archivo: pagina1.html y veremos como se llaman las funciones contenidas en el archivo js:
archivos externos js

Javascript Parte XXXVII

Contiene información sobre el navegador web. La implementación de este objeto varía entre navegadores (IExplorer, FireFox, Opera, etc.)
Las propiedades comunes a estos navegadores son:
appName : almacena el nombre oficial del navegador.
appVersion : almacena la versión del navegador.
cookieEnabled : almacena si las cookies están activas en el navegador.
platform : almacena la plataforma donde el navegador se está ejecutando.
plugins : almacena un array de los plugin cargados en el navegador.
Este pequeño programa muestra los valores de las propiedades antes anunciadas:
<html>
<head>
<title>Problema</title>
</head>
<body>

<script type="text/javascript">
  document.write('Valores de las propiedades del objeto navigator:<br>');
  document.write('appName :' + navigator.appName + '<br>');
  document.write('appVersion :' + navigator.appVersion + '<br>');
  document.write('cookieEnabled :' + navigator.cookieEnabled + '<br>');
  document.write('plugins :' + navigator.plugins.length + '<br>');
  </script>

</body>
</html>