domingo, 1 de octubre de 2017

Javascript Parte LXVI

El evento click se produce cuando el usuario hace un solo clic sobre el elemento HTML y suelta inmediatamente el botón del mouse en el mismo lugar y el dblclick cuando presiona en forma sucesiva en la misma ubicación.
Para probar como registramos estos eventos implementaremos una página que muestre dos div y definiremos el evento click para el primero y el evento dblclick para el segundo.




<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('click',presion1,false);
    document.getElementById('recuadro2').addEventListener('dblclick',presion2,false);
  }

  function presion1()
  {
    alert('se hizo click');
  }

  function presion2()
  {
    alert('se hizo doble click');
  }

</script>

</head>
<body>

<div style="width:200px;height:200px;background:#ffff00" id="recuadro1">
Prueba del evento click
</div>
<div style="width:200px;height:200px;background:#ff5500" id="recuadro2">
Prueba del evento dblclick
</div>

</body>
</html>
Primero registramos mediante la llamada al método addEventListener el evento load de la página (recordemos que esta forma de registrar los eventos no funciona en el IE8 o anteriores, pero en muy poco tiempo la cantidad de dispositivos con dichos navegadores serán ínfimas), y dentro de la función inicio registramos los eventos click y dblclick para los dos div que definimos en la página HTML:
  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('click',presion1,false);
    document.getElementById('recuadro2').addEventListener('dblclick',presion2,false);
  }
Como vemos lo único que hacemos en los métodos que se disparan es mostrar un mensaje:
  function presion1()
  {
    alert('se hizo click');
  }

  function presion2()
  {
    alert('se hizo doble click');
  }

Javascript Parte LXV

El evento keydown se dispara cuando presionamos cualquier tecla del teclado, el evento keyup cuando soltamos una tecla. En cuanto el evento keypress en un principio procesa tanto cuando se la presionó y soltó, el único y gran inconveniente es que la mayoría de los navegadores no dispara el evento keypress para todas las teclas del teclado.
Para probar el evento keyup implementaremos un programa que permita solo ingresar 140 caracteres y nos informe con un mensaje la cantidad de caracteres disponibles para seguir escribiendo.
<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('texto').addEventListener('keyup',presion,false);
  }

  function presion()
  {
    var canti=document.getElementById('texto').value.length;
    var disponibles=140-parseInt(canti);
    document.getElementById('cantidad').innerHTML=disponibles;
  }

</script>

</head>
<body>
<input type="text" id="texto" maxlength="140" size="140">
<br>
<p>Máxama cantidad de caracteres disponibles:<span id="cantidad">140</span></p>
</body>
</html>
Definimos un control text y lo limitamos a 140 como máximo:
<input type="text" id="texto" maxlength="140" size="140">
Disponemos un elemento span para mostrar la cantidad de caracteres como máximo a ingresar:
<p>Máxama cantidad de caracteres disponibles:<span id="cantidad">140</span></p>
Registramos el evento keyup para el control texto:
  function inicio()
  {
    document.getElementById('texto').addEventListener('keyup',presion,false);
  }

Cada vez que se suelta la tecla cuando estamos escribiendo en el control de texto procedemos a extraer el valor del control texto y obtener mediante la propiedad length la cantidad de caracteres tipeados hasta este momento y seguidamente restamos a 140 el número de caractes tipeados y procedemos a mostrarlo en el elemento spam:
  function presion()
  {
    var canti=document.getElementById('texto').value.length;
    var disponibles=140-parseInt(canti);
    document.getElementById('cantidad').innerHTML=disponibles;
  }

Javascript Parte LXIV

El evento mousemove se dispara cada vez que desplazamos la flecha del mouse sobre el elemento HTML que esta escuchando este evento.
Este tipo de evento hay que utilizarlo con cuidado ya que puede sobrecargar el navegador, ya que este evento se dispara cada vez que desplazamos aunque sea solo un pixel.
Implementaremos para ver su funcionamiento una página que muestre un div que capture el evento mousemove y como acción incrementaremos un contador para saber la cantidad de veces que se disparó el evento.

<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mousemove',mover,false);
  }

  function mover()
  {
    var x=parseInt(document.getElementById('cantidad').innerHTML);
    x++;
    document.getElementById('cantidad').innerHTML=x;
  }


</script>

</head>
<body>
<div style="width:200px;height:200px;background:#0000ff" id="recuadro1">
</div>
<p id="cantidad">0</p>

</body>
</html>
Disponemos un div y un párrafo donde mostramos el número 0:
<div style="width:200px;height:200px;background:#0000ff" id="recuadro1">
</div>
<p id="cantidad">0</p>
Capturamos el evento mousemove para el div:
  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mousemove',mover,false);
  }
Cada vez que se emite el evento mousemove se llama el método mover donde extraemos el valor del párrafo, lo incrementamos en uno y lo volvemos a actualizar:
  function mover()
  {
    var x=parseInt(document.getElementById('cantidad').innerHTML);
    x++;
    document.getElementById('cantidad').innerHTML=x;
  }

Javascript Parte LXIII

El evento mouseover se dispara cuando ingresamos con la flecha del mouse a un control HTML que tiene registrado dicho evento, y mouseout se dispara cuando sacamos la flecha del mouse del control.
Es muy común utilizar estos dos eventos para producir cambios en el elemento HTML cuando ingresamos la flecha del mouse y retornar al estado anterior cuando se saca la flecha del mouse.
Es importante hacer notar que estos eventos se disparan sin tener que presionar la flecha del mouse, solo con desplazarla al interior del elemento HTML se dispara el evento mouseover.
Implementaremos un pequeño ejemplo que muestre un cuadrado, el mismo mostrará los bordes redondeados cuando ingresemos la flecha del mouse en su interior y volverá al estado anterior cuando retiremos la flecha.
<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mouseover',entrada,false);
    document.getElementById('recuadro1').addEventListener('mouseout',salida,false);
  }

  function entrada()
  {
    document.getElementById('recuadro1').style.borderRadius='30px';
  }

  function salida()
  {
    document.getElementById('recuadro1').style.borderRadius='0px';
  }

</script>

</head>
<body>
<div style="width:200px;height:200px;background:#0000ff" id="recuadro1">
</div>

</body>
</html>
Definimos en el HTML un div de color azul de 200 píxeles de lado:
<div style="width:200px;height:200px;background:#0000ff" id="recuadro1">
</div>
En la función inicio registramos los eventos mouseover y mouseout:
  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mouseover',entrada,false);
    document.getElementById('recuadro1').addEventListener('mouseout',salida,false);
  }
El método entrada se ejecuta cuando ingresemos la flecha del mouse en el div llamado recuadro1 y procedemos en el mismo a modificar la propiedad borderRadius del estilo de este elemento (indicamos que el redondeo de los vértices del div sea de 30 píxeles):
  function entrada()
  {
    document.getElementById('recuadro1').style.borderRadius='30px';
  }
Cuando sale la flecha del mouse del div se ejecuta la función salida donde fijamos con 0 la propiedad borderRadius:
  function salida()
  {
    document.getElementById('recuadro1').style.borderRadius='0px';
  }

Javascript Parte LXII

Otros dos eventos relacionados con el mouse son mousedown y mouseup.
El evento mousedown se dispara inmediatamente luego que presionamos con la flecha del mouse un elemento HTML que tiene registrado dicho evento.
El evento mouseup se ejecuta luego de soltar el botón del mouse estando dentro del control HTML.
Para probar estos eventos implementaremos una página que contenga dos div, a un div le asignaremos el evento mousedown y al otro el evento mouseup. Cuando ocurra el evento procederemos a cambiar el texto contenido dentro del div.


<html>
<head>

<script type="text/javascript">

  addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mousedown',presion1,false);
    document.getElementById('recuadro2').addEventListener('mouseup',presion2,false);
  }

  function presion1()
  {
    document.getElementById('recuadro1').innerHTML='Se presione el mouse y todavía no se soltó';
  }

  function presion2()
  {
    document.getElementById('recuadro2').innerHTML='Se presione el mouse y se soltó';
  }

</script>

</head>
<body>
<p>Presione el recuadro amarillo sin soltar el botón del mouse.</p>
<div style="width:200px;height:200px;background:#ffff00" id="recuadro1">
</div>
<p>Presione el recuadro naranja y suelte el botón del mouse.</p>
<div style="width:200px;height:200px;background:#ff5500" id="recuadro2">
</div>

</body>
</html>
En la función inicio registramos los eventos mousedown y mouseup para los dos div, al div recuadro1 procedemos a registrar el evento mousedown y al div recuadro2 procedemos a registrar el evento mouseup:
  function inicio()
  {
    document.getElementById('recuadro1').addEventListener('mousedown',presion1,false);
    document.getElementById('recuadro2').addEventListener('mouseup',presion2,false);
  }
El método que se dispara para el primer div procedemos a modificar todo el contenido del div accediendo a la propiedad innerHTML:
  function presion1()
  {
    document.getElementById('recuadro1').innerHTML='Se presione el mouse y todavía no se soltó';
  }
De forma similar codificamos la función que modifica el segundo div:
  function presion2()
  {
    document.getElementById('recuadro2').innerHTML='Se presione el mouse y se soltó';
  }

lunes, 4 de septiembre de 2017

Javascript Parte LXI

Como hemos visto hasta ahora uno de los usos principales de JavaScript es la implementación de algoritmos que reaccionan a eventos que se producen en una página web. Cuando se termina de cargar completamente una página web se dispara el evento onload, cuando se presiona un botón de tipo submit se dispara el evento onsubmit, cuando movemos la flecha del mouse se dispara onmousemove y otra gran cantidad de eventos que nos informa el navegador y nosotros podemos capturarlos y hacer un algoritmo a nuestra medida.
JavaScript implementa tres formas distintas de capturar los eventos que emite el navegador.

Eventos definidos directamente en la marca HTML.

Esta metodología esta en desuso, de todos modos muchos sitios creados a fines de 1990 y principios del 2000 implementan esta técnica.
Problema
Implementar un formulario que solicite la carga del nombre de usuario y su clave. Mostrar un mensaje si no se ingresan datos en alguno de los dos controles.
<html>
<head>

<script type="text/javascript">

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       return false;
     }
     else
       return true;
  }

</script>

</head>
<body>

<form method="post" action="procesar.php" onsubmit="validar();" id="formulario1">
Ingrese nombre:
<input type="text" id="usuario" name="usuario" size="20">
<br>
Ingrese clave:
<input type="password" id="clave" name="clave" size="20">
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>

</body>
</html>
Lo primero que tenemos que ver que la marca form define la propiedad onsubmit y le asigna el nombre de la función JavaScript que debe llamarse previo a que el navegador empaquete todos los datos del formulario y los envía al servidor para ser procesados:
<form method="post" action="procesar.php" onsubmit="validar();">
Como vemos debemos indicar el nombre de la función y los paréntesis (en este caso no se envían parámetros por lo que los paréntesis van abiertos y cerrados)
En el bloque JavaScript debemos implementar la función validar donde extraemos los valores de cada control y verificamos si alguno de los dos no tiene cargado caracteres, en caso que suceda esto mostramos un mensaje y retornamos un false para que el navegador no envíe los datos del formulario al servidor. Si la función retorna true los datos del formulario son enviados por el navegador al servidor:
<script type="text/javascript">

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       return false;
     }
     else
       return true;
  }

</script>
Esta metodología de inicializar eventos debe ser evitada en todo lo posible.

Eventos definidos accediendo a propiedades del objeto.

Esta metodología es todavía ampliamente utilizada ya que la mayoría de los navegadores lo implementan en forma similar.
Problema
Implementar un formulario que solicite la carga del nombre de usuario y su clave. Mostrar un mensaje si no se ingresan datos en alguno de los dos controles.
<html>
<head>

<script type="text/javascript">

  window.onload=inicio;

  function inicio()
  {
    document.getElementById("formulario1").onsubmit=validar;
  }

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       return false;
     }
     else
       return true;
  }

</script>

</head>
<body>

<form method="post" action="procesar.php" id="formulario1">
Ingrese nombre:
<input type="text" id="usuario" name="usuario" size="20">
<br>
Ingrese clave:
<input type="password" id="clave" name="clave" size="20">
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>

</body>
</html>
Con esta segunda metodología vemos que el código HTML queda limpio de llamadas a funciones JavaScript y todo el código queda dentro del bloque del script (pudiendo luego llevar todo este bloque a un archivo externo *.js)
Lo primero que vemos es inicializar la propiedad onload del objeto window con el nombre de la función que se ejecutará cuando finalice la carga completa de la página, es importante notar que a la propiedad onload le asignamos el nombre de la función y NO debemos disponer los paréntesis abiertos y cerrados (ya que no se está llamando a la función sino le estamos pasando la dirección o referencia de la misma)
  window.onload=inicio;
La función inicio es llamada por el objeto window cuando se termina de cargar la página. En esta función obtenemos la referencia del objeto formulario1 mediante el método getElementById e inicializamos la propiedad onsubmit con el nombre de la función que será llamada cuando se presione el botón submit del formulario:
  function inicio()
  {
    document.getElementById("formulario1").onsubmit=validar;
  }
Por último tenemos la función validar que verifica si los dos controles del formulario están cargados:
  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       return false;
     }
     else
       return true;
  }
La misma metodología pero utilizando funciones anónimas para cada evento el código ahora queda condensado:
<html>
<head>

<script type="text/javascript">

  window.onload=function() {
    document.getElementById("formulario1").onsubmit=function () {
      var usu=document.getElementById("usuario").value;
      var cla=document.getElementById("clave").value;
      if (usu.length==0 || cla.length==0)
      {
        alert('El nombre de usuario o clave está vacío');
        return false;
      }
      else
        return true;
    }
  }

</script>

</head>
<body>

<form method="post" action="procesar.php" id="formulario1">
Ingrese nombre:
<input type="text" id="usuario" name="usuario" size="20">
<br>
Ingrese clave:
<input type="password" id="clave" name="clave" size="20">
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>

</body>
</html>
Analicemos un poco el código implementado, a la propiedad onload del objeto window le asignamos una función anónima:
  window.onload=function() {
     ...
  }
En la implementación de la función anónima inicializamos la propiedad onsubmit del objeto formulario1 con otra función anónima:
    document.getElementById("formulario1").onsubmit=function () {
      ...
    }
Esta sintaxis de funciones anónimas es ampliamente utilizado.

Modelo de eventos definidos por W3C (World Wide Web Consortium)

Este modelo de eventos se basa en la implementación de un método para todos los objetos que nos permite registrar eventos. La sintaxis del método es:
  addEventListener(evento, método a ejecutar, fase);
Veamos como implementamos el problema anterior utilizando este nuevo modelo de eventos:
<html>
<head>

<script type="text/javascript">

  window.addEventListener('load',inicio,false);

  function inicio()
  {
    document.getElementById("formulario1").addEventListener('submit',validar,false);
  }

  function validar(evt)
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       evt.preventDefault();
     }
  }

</script>

</head>
<body>

<form method="post" action="procesar.php" id="formulario1">
Ingrese nombre:
<input type="text" id="usuario" name="usuario" size="20">
<br>
Ingrese clave:
<input type="password" id="clave" name="clave" size="20">
<br>
<input type="submit" id="confirmar" name="confirmar" value="Confirmar">
</form>

</body>
</html>
Lo primero que vemos es que en vez de inicializar la propiedad onload procedemos a llamar al método addEventListener:
  window.addEventListener('load',inicio,false);
El primer parámetro es un string con el nombre del evento a inicializar, el segundo parámetro es el nombre de la función a ejecutar y el tercer parámetro normalmente es el valor false.
Cuando se carga completamente la página el objeto window tiene la referencia al método que se debe llamar, en nuestro caso se llama inicio. La función inicio obtiene la referencia del objeto formulario1 y procede a registrar el evento submit indicando en el segundo parámetro el nombre de la función que debe ejecutarse:
  function inicio()
  {
    document.getElementById("formulario1").addEventListener('submit',validar,false);
  }
El código de la función validar se modifica, llega como parámetro una referencia al evento y mediante este llamamos al método preventDefault si queremos que no se envíen los datos al servidor:
  function validar(evt)
  {
     var usu=document.getElementById("usuario").value;
     var cla=document.getElementById("clave").value;
     if (usu.length==0 || cla.length==0)
     {
       alert('El nombre de usuario o clave está vacío');
       evt.preventDefault();
     }
  }
Este modelo de eventos está siendo ampliamente implementado por los navegadores modernos. El problema es el IE8 o inferiores que no lo implementa de esta forma.

Javascript Parte LX

Hasta ahora siempre que hemos implementado una función le hemos pasado como parámetro tipos de dato numérico, string, boolean, objetos etc.
Ahora veremos que también podemos implementar funciones que reciban como parámetro otra función.
Primero veamos un simple ejemplo para entender que una función se la podemos asignar a una variable y luego a través de esta variable llamar a la función:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var f1=function(x,y)
  {
    var s=x+y;
    return s;
  }

  document.write(f1(4,6)+'<br>');  
  var f2=f1;
  document.write(f2(3,3)+'<br>');    

</script>

</body>
</html>
Vemos que definimos una variable llamada f1 y le asignamos la función propiamente dicha:
  var f1=function(x,y)
  {
    var s=x+y;
    return s;
  }
Luego para llamar la función lo hacemos a través de la variable f1:
  document.write(f1(4,6)+'<br>');  
De la misma manera podemos definir una segunda variable que obtenga la referencia de la otra variable y podremos entonces llamar a la misma función con este segundo nombre:
  var f2=f1;
  document.write(f2(3,3)+'<br>');    
Problema
Ahora si implementaremos otro problema que declare una función que reciba tres parámetros, el último de ellos es una función:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function calcular(x,y,fu)
  {
    var resu=fu(x,y);
    return resu;
  }

  var s1=calcular(10,5,function (v1,v2) {
    return v1+v2;
  });
  
  document.write(s1+'<br>');

  var s2=calcular(10,5,function (v1,v2) {
    return v1-v2;
  });
  
  document.write(s2+'<br>');


</script>

</body>
</html>
Es importante entender la sintaxis que presentamos en este problema elemental para entender que una función puede recibir como parámetros una función y luego llamarla desde dentro.
Primero analicemos como llamamos a la función calcular:
  var s1=calcular(10,5,function (v1,v2) {
    return v1+v2;
  });
A la función calcular le pasamos dos enteros:10 y 5, y una función que definimos en el mismo parámetro:
function (v1,v2) {
    return v1+v2;
}
La función calcular recibe los tres parámetros y sabiendo que el tercer parámetro llega la referencia a la función procedemos a llamarla enviando los dos parámetros requeridos:
  function calcular(x,y,fu)
  {
    var resu=fu(x,y);
    return resu;
  }
Como vemos podemos llamar nuevamente a la función calcular pero pasando otra función:
  var s2=calcular(10,5,function (v1,v2) {
    return v1-v2;
  });
Podemos en vez de definir funciones anónimas cuando llamamos a calcular pasar el nombre de funciones declaradas:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function sumar(v1,v2) 
  {
    return v1+v2;
  }

  function restar(v1,v2) 
  {
    return v1-v2;
  }

  function calcular(x,y,fu)
  {
    var resu=fu(x,y);
    return resu;
  }

  var s1=calcular(10,5,sumar);
  
  document.write(s1+'<br>');

  var s2=calcular(10,5,restar);
  
  document.write(s2+'<br>');

</script>

</body>
</html>
Podemos observar que definimos las funciones sumar y restar:
  function sumar(v1,v2) 
  {
    return v1+v2;
  }

  function restar(v1,v2) 
  {
    return v1-v2;
  }
Y cuando llamamos a calcular en el tercer parámetro indicamos el nombre de la función a enviarle:
  var s1=calcular(10,5,sumar);

Javascript Parte LIX

JavaScript permite definir funciones dentro de otras funciones:
<html>
<head>
<script type="text/javascript">


  function generarListaOrdenada(vec)
  {
    function comienzo()
    {
      s='<ol>';
    }
  
    function fin()
    {
      s=s+'</ol>';
    }
    
    var s='';
    comienzo();
    var f;
    for(f=0;f<vec.length;f++)
    {
      s=s+'<li>'+vec[f]+'</li>';
    }
    fin();
    return s;
  }


  onload=function() {
    var opciones=['Opción a','Opción b','Opción c','Opción d'];
    document.getElementById('div1').innerHTML=generarListaOrdenada(opciones);
  }

</script>

</head>
<body>
<div id="div1"></div>
</body>
</html>
Como vemos en el ejemplo la función generarListaOrdenada contiene el algoritmo propiamente dicho y además declara dos funciones llamadas comienzo y fin.
Las funciones anidadas solo pueden ser llamadas desde el interior de la función que las contiene. En este ejemplo la función generarListaOrdenada tiene por objetivo generar un string con una serie de marcas HTML que genere una lista ordenada.
Lo primero en la función generarListaOrdenada es declarar las dos funciones anidadas:
    function comienzo()
    {
      s='<ol>';
    }
  
    function fin()
    {
      s=s+'</ol>';
    }
Pero lo primero que se ejecuta al llamar a la función generarListaOrdenada es:
    var s='';
    comienzo();
    var f;
    for(f=0;f<vec.length;f++)
    {
      s=s+'<li>'+vec[f]+'</li>';
    }
    fin();
    return s;
Es decir primero se define la variable local s y se inicializa con un string vacío. Seguidamente se llama a la función comienzo que tiene por objetivo cargar en la variable s el valor '<ol>'.
Cuando finaliza de ejecutarse la función interna continua con el for definido en la función generarListaOrdenada:
    for(f=0;f<vec.length;f++)
    {
      s=s+'<li>'+vec[f]+'</li>';
    }
Finalmente cuando sale del for se llama a la segunda función anidada llamada fin:
    fin();
Las funciones anidadas pueden acceder a las variables locales de la función que las contiene (en este caso pueden acceder a la variable s)
Luego la función generarListaOrdenada completa queda con la sintaxis:
  function generarListaOrdenada(vec)
  {
    function comienzo()
    {
      s='<ol>';
    }
  
    function fin()
    {
      s=s+'</ol>';
    }
    
    var s='';
    comienzo();
    var f;
    for(f=0;f<vec.length;f++)
    {
      s=s+'<li>'+vec[f]+'</li>';
    }
    fin();
    return s;
  }
A la función generarListaOrdenada la llamamos desde la función anónima que definimos para el evento onload de la página. Cargamos en el elemento div definido dentro de la página el código HTML que genera una lista ordenada:
  onload=function() {
    var opciones=['Opción a','Opción b','Opción c','Opción d'];
    document.getElementById('div1').innerHTML=generarListaOrdenada(opciones);
  }
Las funciones anidadas no se las puede llamar desde fuera de la función que las contiene, por ejemplo produce un error si intentamos llamar a la función "comienzo" desde fuera de la función generarListaOrdenada:
  onload=function() {
    var opciones=['Opción a','Opción b','Opción c','Opción d'];
    comienzo();
    document.getElementById('div1').innerHTML=generarListaOrdenada(opciones);
  }

Javascript Parte LVIII

Cuando definimos una función podemos emplear letras minúsculas, mayúsculas, números siempre y cuando no ocupe la primer posición en el nombre, el caracter '_' y el caracer '$'
Una convención muy extendida cuando se define una función es comenzar la primera palabra en minúscula y a partir de la segunda palabra disponer el primer caracter en mayúsculas:
<html>
<head>
</head>
<body>

<script type="text/javascript">
 
  function calcularPerimetro(lado)
  {
    var per=lado*4;
    return per;
  }

  var l=prompt('Ingrese valor del lado:','');
  l=parseInt(l);
  document.write(calcularPerimetro(l));

</script>

</body>
</html>
El nombre de la función en este ejemplo es: calcularPerimetro
Como vemos la primer palabra "calcular" hemos utilizado todo minúsculas y en la segunda palabra disponemos en mayúsculas el primer caracter "Perimetro".
Las funciones estándares de JavaScript tienen esta convención:
parseInt
parseFloat
prompt
Los métodos de distintas clases (Date, String) también cumplen esta convención:
 getYear()
 setYear(año)
 getFullYear()

 toUpperCase()
 toLowerCase()
 indexOf()

 etc.
Siempre es conveniente utilizar nombres de funciones que sean significativas con el algoritmo que implementan: calcularPerimetro, sumar, calcularRaizCuadrada etc.
La regla de definir un nombre de función lo más claro posible puede saltearse con funciones que se utilizan constantemente (por ejemplo la librería JQuery de JavaScript define una función que tiene como nombre solo el caracter $)
Emplear un solo caracter para definir un nombre de función solo se aconseja para funciones de uso masivo.
Problema
Definir una función llamada $ que reciba como parámetro el id de un elemento HTML y retorne la referencia del mismo.
<html>
<head>

<script type="text/javascript">

  function $(ele)
  {
    return document.getElementById(ele);
  }

  function inicio()
  {
    $('cuerpo').style.backgroundColor='#ffff00';
  }

  window.onload=inicio;

</script>

</head>
<body id="cuerpo">

</body>
</html>
La función $ recibe como parámetro el id de un elemento HTML y mediante el método getElementById extrae la referencia y lo retorna:
  function $(ele)
  {
    return document.getElementById(ele);
  }
La función inicio se ejecuta luego que la página está completamente cargada. Llama a la función $ pasando el id del body de la página y con el valor devuelto accedemos a la propiedad style del objeto:
  function inicio()
  {
    $('cuerpo').style.backgroundColor='#ffff00';
  }

Javascript Parte LVII

Las variables locales se definen dentro de una función y solo se tiene acceso dentro de la misma función. Una variable local se la define antecediendo la palabra clave var al nombre de la variable.
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function imprimir()
  {
    var x=10;
    document.write(x);
  }

  imprimir();

</script>

</body>
</html>
Luego decimos que x es una variable local que solo se la puede acceder dentro de la función imprimir. Si intentamos acceder a la variable x fuera de la función se produce un error en tiempo de ejecución:
<script type="text/javascript">

  function imprimir()
  {
    var x=10;
    document.write(x);
  }

  imprimir();
  document.write(x);  //error en tiempo de ejecución

  </script>
Las variables globales son las que definimos fuera de cualquier función. Una variable global tenemos acceso fuera y dentro de las funciones:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function imprimir()
  {
    document.write(global1+'<br>');  // muestra un 100
    global1++;
  }

  var global1=100;
  imprimir();
  document.write(global1);  // muestra un 101

</script>

</body>
</html>
Como podemos observar el programa anterior hemos definido la variable global1 e inicializado con el valor 100. Luego dentro de la función podemos acceder para imprimirla y modificarla. Podemos ver luego si la accedemos fuera de la función su valor fue modificado.
Todas las variable globales se convierten en atributos del objeto window, luego podemos acceder a la variable por su nombre o antecediendo el nombre del objeto:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var global1=100;
  document.write(global1+'<br>');        //100
  document.write(window.global1+'<br>'); //100

</script>

</body>
</html>
Cuidado
Cuando definimos variables locales dentro de una función tenemos que no olvidarnos de anteceder al nombre de la variable la palabra var, en caso de olvidarnos se creará automáticamente una variable global con dicho nombre:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  function imprimir()
  {
    x=100;
    document.write(x+'<br>');
  }

  imprimir();
  document.write(x+'<br>');
  
</script>

</body>
</html>
En el ejemplo superior en la función imprimir se está creando una variable global llamada x. Como podemos ver luego fuera de la función cuando imprimimos x vemos que no produce error y muestra el valor 100. Con solo agregar la palabra clave var vemos que nos muestra un mensaje de error al tratar de acceder a una variable inexistente:
  function imprimir()
  {
    var x=100;
    document.write(x+'<br>');
  }

  imprimir();
  document.write(x+'<br>');
El JavaScript moderno introduce una directiva para salvar este y otros problemas muy comunes. Si activamos modo estricto todas las variables en JavaScript deben declarase sino se produce un error. Veamos como introducimos esta directiva de modo estricto:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  'use strict';

  function imprimir()
  {
    x=100; //error
    document.write(x+'<br>');
  }

  imprimir();
  document.write(x+'<br>');
  
</script>

</body>
</html>
La directiva de modo estricto se emplea las palabras claves use strict entre comillas simples o dobles y un punto y coma. Solo los navegadores modernos implementan los análisis de modo estricto.
La razón de disponer la directiva entre comillas y con un punto y coma es para que navegadores antiguos pasen por alto el string (ya que el string no se asigna a nadie el navegador antiguo no lo tiene en cuenta)
Activando el modo estricto luego cuando tratamos de asignar el valor 100 a la variable x se produce un error ya que no se nos permite crear una variable global (esto nos evita problemas de crear variables globales en funciones por error)

domingo, 6 de agosto de 2017

Javascript Parte LVI

Cuando llamamos a una función JavaScript crea automáticamente un objeto llamado "arguments" que almacena los valores que le pasamos a dicha función. También este objeto arguments almacena en una propiedad llamada length la cantidad de parámetros que llegaron. Veamos un ejemplo muy sencillo.
Confeccionar una función que retorne la suma de dos enteros:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function sumar(x,y)
  {
    var s=x+y;
    return s;
  }

  document.write(sumar(5,3));

</script>

</body>
</html>
Luego podemos resolver esta misma función accediendo al objeto arguments que se crea cada vez que llamamos a una función:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function sumar(x,y)
  {
    var s=arguments[0]+arguments[1];
    return s;
  }

  document.write(sumar(5,3));

</script>

</body>
</html>

Como podemos observar dentro de la función sumar accedemos al primer parámetro mediante el objeto arguments (con el subíndice 0 accedemos al primer parámetro llamado x) Tenemos dos formas de acceder al primer parámetro de la función : con el nombre x o con arguments[0].
Como podemos observar si debemos sumar dos valores que llegan como parámetro el algoritmo más claro es el primero en lugar que tener que acceder al objeto "arguments", pero veremos que en muchas situaciones el objeto "arguments" nos favorece en la implementación de funciones mucho más complejas y reutilizables.
Problema
Confeccionar una función que reciba un conjunto variable de enteros y nos retorne su suma:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  function sumar()
  {
    var s=0;
    var f;
    for(f=0; f<arguments.length; f++)
    {
      s=s+arguments[f];
    }
    return s;
  }

  document.write(sumar(2,4));
  document.write('<br>');
  document.write(sumar(1,2,3,4,5));
  document.write('<br>');
  document.write(sumar(100,200,300));

</script>

</body>
</html>
Como no sabemos con cuantos parámetros llamaremos a la función sumar no indicamos ningún parámetro. Luego la única forma de acceder a los parámetros es mediante el objeto "arguments" y por medio del subíndice accedemos uno a uno. También el objeto "arguments" tiene una propiedad length que almacena la cantidad de parámetros recibidos por la función.
Esta sintaxis nos permite codificar funciones muy poderosas que se adaptan a muchas situaciones, como vemos luego podemos llamar a la función sumar pasando 2 parámetros:
  document.write(sumar(2,4));
5 parámetros:
  document.write(sumar(1,2,3,4,5));
3 parámetros:
  document.write(sumar(100,200,300));
etc.
Problema
Confeccionar una función que reciba un conjunto de string y genere dentro de la página una lista ordenada (<ol>). La función debe recibir en el primer parámetro el id de un div.
<html>
<head>
</head>

<script type="text/javascript">

  window.onload=iniciar;

  function iniciar()
  {
    generarLista('lista1','uno','dos','tres','cuatro','cinco','seis');
  }

  function generarLista()
  {
    var s='<ol>';
    var f;
    for(f=1;f<arguments.length;f++)
    {
      s=s+'<li>'+arguments[f]+'</li>';
    }
    s=s+'</ol>';
    var elemento1=document.getElementById(arguments[0]);
    elemento1.innerHTML=s;
  }

</script>


<body>
<div id="lista1"></div>
</body>
</html>
Veamos por partes el funcionamiento de este programa. En el body de la página hemos definido un div con id llamado "lista1" sin contenido:
<body>
<div id="lista1"></div>
</body>
En el bloque del script inicializamos la propiedad onload del objeto window indicando la función a ejecutar luego que la página esta completamente cargada:
  window.onload=iniciar;
Es decir que la función iniciar se ejecuta una vez que la página está completamente construida (es decir ya está en memoria el div definido en el body)
La función iniciar es la que llama a la función generarLista pasando como parámetros primero el id del div a cargar y a partir del segundo parámetro en adelante los distintos string a mostrar en cada elemento del <ol>:
  function iniciar()
  {
    generarLista('lista1','uno','dos','tres','cuatro','cinco','seis');
  }
Finalmente la función generarLista que como podemos observar no tiene parámetros explícitos, sino que los accedemos luego mediante el objeto arguments. Disponemos un for que lo inicializamos en 1 ya que el argumento cero tiene el nombre del id del div:
  function generarLista()
  {
    var s='<ol>';
    var f;
    for(f=1;f<arguments.length;f++)
    {
      s=s+'<li>'+arguments[f]+'</li>';
    }
    s=s+'</ol>';
    var elemento1=document.getElementById(arguments[0]);
    elemento1.innerHTML=s;
  }
Mediante el método getElementById obtenemos la referencia del div que llega como parámetro en el arguments[0]. y luego mediante la propiedad innerHTML indicamos todo el código HTML que debe cargarse en el div. En este caso almacenamos en la variable s todas las marcas necesarios para generar la lista ordenada.

Javascript Parte LV

Para visitar todas las componentes de un vector hemos visto hasta ahora el ciclo repetitivo for:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  var vec=[10,20,30,40,50];
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'-');
  }

</script>

</body>
</html>
Javascript cuenta con otra variante de for(llamada for in):
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  var vec=[10,20,30,40,50];
  for(var indice in vec)
  {
    document.write(indice);
    document.write(vec[indice]+'-');
  }
</script>

</body>
</html>
El for se repite tantas veces como elementos tiene el vector y en cada vuelta del ciclo for la variable indice almacena el subíndice de la componente (tengamos en cuenta que en este ejemplo definimos el vector con los valores 10,20,30,40,50 y se almacenaron en los subíndices 0,1,2,3,4) es decir la variable indice almacenará en la primer vuelta el valor 0, en la segunda el valor 1 y así sucesivamente:
  for(var indice in vec)
  {
    document.write(indice);
    document.write(vec[indice]+'-');
  }
Si tenemos un vector no denso (es decir que tiene algunas posiciones vacías el empleo del for in tiene un resultado distinto al empleo del for clásico):
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  var vec=[10,,30,,50];
  document.write('Recorredo del vector con un for clásico<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'-');
  }
  document.write('<br>');
  document.write('Recorredo del vector con un for in<br>');
  for(var indice in vec)
  {
    document.write(vec[indice]+'-');
  }
</script>

</body>
</html>
El resultado de la ejecución del programa es:
Recorrido del vector con un for clásico
10-undefined-30-undefined-50-
Recorredo del vector con un for in
10-30-50-
Como podemos comprobar con el for in no se acceden a componentes inexistentes.

Javascript Parte LIV

El método toString del objeto Array retorna un string con todos los elementos del vector separados por coma.
Problema
Crear un vector con 10 elementos con valores aleatorios comprendidos entre 0 y 1000. Luego copiar el contenido del vector a un string con los valores de las componentes separados por coma:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=new Array(10);
  var f;
  for(f=0;f<vec.length;f++)
  {
    vec[f]=parseInt(Math.random()*1001);
  }
  var cadena=vec.toString();
  document.write(cadena);
 
</script>

</body>
</html>
El resultado de la ejecución del programa es (como son valores aleatorios es casi seguro que tendrá una lista de 10 valores distintos a estos):
348,860,430,568,428,692,281,159,573,284
Como podemos observar para copiar todas las componentes del vector en un string y que queden separadas por coma llamamos al método toString():
  var cadena=vec.toString();

Javascript Parte LIII

El método concat crea un nuevo vector con los datos del objeto original y los datos que le enviamos como parámetro.
Veamos con un ejemplo los resultados que obtenemos con el método concat:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[10,20,30,40];
  var vecnuevo=vec.concat(1,2,3);
  document.write('Vector origen<br>');
  document.write(vec.join()+'<br>');
  document.write('Vector generado<br>');
  document.write(vecnuevo.join()+'<br>');
 
</script>

</body>
</html>

Por pantalla tenemos el siguiente resultado:
Vector origen
10,20,30,40
Vector generado
10,20,30,40,1,2,3
El vector llamado vec almacena 4 componentes. Luego el vector que retorna el método concat es [10,20,30,40,1,2,3], el vector "vec" no se modifica al llamar al método concat. Como podemos observar los elementos que le pasamos como parámetro se almacenan al final del vector generado.
Otra variante es que podemos pasar como parámetros al metodo concat otros vectores:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec1=[10,20,30,40];
  var vec2=[100,200,300,400];
  var vecsuma=vec1.concat(vec2);
  document.write('Primer vector:');
  document.write(vec1.join()+'<br>');
  document.write('Segundo vector:');
  document.write(vec2.join()+'<br>');
  document.write('vectores concatenados:');
  document.write(vecsuma.join()+'<br>');
 
</script>

</body>
</html>
En pantalla tenemos como resultado:
Primer vector:10,20,30,40
Segundo vector:100,200,300,400
vectores concatenados:10,20,30,40,100,200,300,400
En este segundo problema tenemos dos vectores llamados vec1 y vec2. Llamamos al método concat a través del objeto vec1 y le pasamos como parámetro el vec2. El resultado es otro vector que se almacena la referencia en la variable vecsuma.
Luego mostramos los elementos de los vectores ayudándonos con la llamada del método join para generar un string con todos los elementos del vector separados por coma.


Fuente: 
http://www.tutorialesprogramacionya.com

Javascript Parte LII

El método join concatena todos los elementos del vector en un único string.
Al método join le pasamos como parámetro el o los caracteres de separación que debe agregar entre los elementos dentro del string que se genera.
Veamos un ejemplo del funcionamiento del método join:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  var vec=[10,20,30,40,50]; 
  var cadena=vec.join('-');
  document.write(cadena);

</script>

</body>
</html>
El resultado en pantalla es:
10-20-30-40-50
Como podemos observar el string cadena almacena todos los elementos del vector separados por el caracter "-".
Podemos disponer más de un caracter de separación:
  var vec=[10,20,30,40,50]; 
  var cadena=vec.join('---');
  document.write(cadena); //10---20---30---40---50
Podemos llamar al método join inclusive sin parámetros, en dicho caso se agrega por defecto el caracter de la coma:
  var vec=[10,20,30,40,50]; 
  var cadena=vec.join();
  document.write(cadena);  //10,20,30,40,50

sábado, 1 de julio de 2017

Javascript Parte LI

El método slice (traducido al castellano: trozo) retorna un trozo del vector. La sintaxis es:
 vec.slice(2,4);
El primer parámetro indica a partir de que elementos debe retornar y el segundo parámetro hasta cual elemento (sin incluir dicha posición)
El método slice no modifica el vector original, sino que retorna otro vector con las componentes indicadas.
Veamos con un ejemplo el empleo del método slice:
<html>
<head>
</head>
<body>

<script type="text/javascript">
  
  var vec=[10,20,30,40,50,60];
  document.write('Vector original<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'-');
  }
  document.write('<br>');
  var vec2=vec.slice(1,4);
  document.write('Vector resultante de la llamada a slice<br>');
  for(f=0;f<vec2.length;f++)
  {
    document.write(vec2[f]+'-');
  }
</script>

</body>
</html>
Estamos indicando en el método slice que retorne un nuevo vector a partir del elemento de la posición 1 hasta la posición 4 sin incluirla. El vector original (es decir vec) no se modifica con la llamada al método slice. El resultado de la ejecución de este programa es:
Vector original
10-20-30-40-50-60-
Vector resultante de la llamada a slice
20-30-40-
Otras variantes que podemos emplear con el método slice:
  • Si queremos extraer desde una determinada posición hasta el final del vector debemos llamar al método slice con un solo parámetro:
       var vec=[10,20,30,40,50,60];
       var vec2=vec.slice(2); // vec2 almacena [30,40,50,60]
    
  • Si queremos indicar una posición pero comenzando desde el final del vector debemos indicar un valor negativo en el primer parámetro:
      var vec=[10,20,30,40,50,60];
      var vec2=vec.slice(-2); // vec2 almacena [50,60]
    
    También podemos indicar el segundo parámetro:
      var vec=[10,20,30,40,50,60];
      var vec2=vec.slice(-3,-1); // vec2 almacena [40,50]  
    
  • Por último podemos indicar el primer parámetro un valor positivo y el segundo un valor negativo indicando una posición desde el final
      var vec=[10,20,30,40,50,60];
      var vec2=vec.slice(1,-1); // vec2 almacena [20,30,40,50]
    

Javascript Parte L

El método splice permite eliminar componentes, insertar componentes o eliminar e insertar componentes en forma simultánea.
Borrar
Veamos primero como podemos utilizar este método para borrar elementos. Para borrar elementos debemos indicar dos parámetros al método splice, el primero indica a partir de que posición procedemos a borrar componentes y el segundo parámetro indica la cantidad de componentes a borrar.
Veamos con un ejemplo como eliminamos 3 componentes del vector a partir de la segunda componentes:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[0,1,2,3,4,5,6,7,8,9];
  document.write('Vector inicial<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.splice(1,3);
  document.write('Vector luego de borrar<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
Por pantalla obtenemos como resultado:
Vector inicial
0
1
2
3
4
5
6
7
8
9
Vector luego de borrar
0
4
5
6
7
8
9
Con la llamada al método splice:
  vec.splice(1,3);
estamos indicando que a partir de la componente de la posición 1 (recordemos que los vectores se enumeran a partir de cero) proceda a eliminar 3 componentes.
Otra cosa que hay que tener en cuenta que el método splice retorna un vector con los elementos borrados, luego si queremos podemos guardar esa referencia:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[0,1,2,3,4,5,6,7,8,9];
  document.write('Vector inicial<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  var vec2=vec.splice(1,3);
  document.write('Elementos extraídos<br>');
  var f;
  for(f=0;f<vec2.length;f++)
  {
    document.write(vec2[f]+'<br>');
  }

</script>

</body>
</html>
El resultado es:
Vector inicial
0
1
2
3
4
5
6
7
8
9
Elementos extraídos
1
2
3
Podemos indicar un valor negativo y el posicionamiento se cuenta desde el final del vector, por ejemplo si queremos eliminar los dos últimos elementos del vector luego debemos codificar:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[0,1,2,3,4,5,6,7,8,9];
  document.write('Vector inicial<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.splice(-2,2);
  document.write('Eliminados los dos últimos elementos<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
El resultado en pantalla es:
Vector inicial
0
1
2
3
4
5
6
7
8
9
Eliminados los dos últimos elementos
0
1
2
3
4
5
6
7
Insertar
Veamos ahora como procedemos a insertar valores dentro del vector. Debemos pasar como mínimo 3 o más parámetros. Los dos primeros cumplen la misma función que cuando borramos (pero en este caso pasamos un cero en el segundo parámetro) y del tercer parámetro en adelante se indican los valores a insertar en el vector.
Codificaremos un programa que inserte los valores 10,20,30,40 a partir de la segunda componente:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[0,1,2,3,4,5,6,7,8,9];
  document.write('Vector inicial<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.splice(1,0,10,20,30,40);
  document.write('Vector luego insertar 4 valores<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
El resultado por pantalla es:
Vector inicial
0
1
2
3
4
5
6
7
8
9
Vector luego insertar 4 valores
0
10
20
30
40
1
2
3
4
5
6
7
8
9
En esta llamada al método splice indicamos que a partir de la posición 1 del vector borre cero componentes e inserte los valores 10,20,30 y 40:
  vec.splice(1,0,10,20,30,40);
Borrar e insertar
La tercer posibilidad que nos presenta este método es en el mismo momento que borramos elementos procedemos a insertar otros.
Para probar el borrar e insertar en forma simultánea confeccionaremos un programa que borre desde la posición 1 tres elementos e inserte otros cinco elementos:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[0,1,2,3,4,5,6,7,8,9];
  document.write('Vector inicial<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.splice(1,3,10,20,30,40,50);
  document.write('Vector luego de borrar 3 elementos e insertar otros 5 valores<br>');
  var f;
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
El resultado por pantalla es:
Vector inicial
0
1
2
3
4
5
6
7
8
9
Vector luego de borrar 3 elementos e insertar otros 5 valores
0
10
20
30
40
50
4
5
6
7
8
9

Javascript Parte XLIX

Otro método muy útil de la clase Array es sort. La sintaxis más sencilla y por defecto es para ordenar una lista de string:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var nombres=['marcos','ana','luis','jorge','carlos'];
  var f;
  document.write('Vector antes de ordenarlo<br>');
  for(f=0;f<nombres.length;f++)
  {
    document.write(nombres[f]+'<br>');
  }
  nombres.sort();
  document.write('Vector después de ordenarlo<br>');
  for(f=0;f<nombres.length;f++)
  {
    document.write(nombres[f]+'<br>');
  }

</script>

</body>
</html>
Como vemos creamos un vector con una lista de string:
  var nombres=['marcos','ana','luis','jorge','carlos'];
Luego con llamar simplemente al método sort el mismo se encarga de intercambiar las componentes de tal forma que el menor alfabéticamente se encuentra al principio y así sucesivamente:
  nombres.sort();
Para ordenar una lista de enteros se complica el algoritmo ya que debemos pasar al método sort una función anónima indicando como implementar la comparación entre elementos:
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[100,5,60,3,90];
  var f;
  document.write('Vector antes de ordenarlo<br>');
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.sort(function(v1,v2) {
    if (v1>v2)
      return 1;
    else
      return 0;
  });
  document.write('Vector después de ordenarlo<br>');
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
Como vemos al método sort hemos pasado una función que retorna un 1 o 0:
  vec.sort(function(v1,v2) {
    if (v1>v2)
      return 1;
    else
      return 0;
  });
Los parámetros v1 y v2 son los elementos que se comparan. Si v1 es mayor a v2 significa que queremos intercambiarlos para que el mayor se desplace hacia el final del vector. Esta función debe retornar un valor mayor a cero si queremos que se intercambien los elementos y cero si queremos dejar los dos elementos del vector sin ser intercambiados.
El siguiente método a analizar en este concepto es reverse(), como podemos intuir este método invierte el orden de los elementos del vector. Nos puede ser de utilidad si tenemos ordenado un vector en orden ascendente y lo queremos en forma descendente.
Problema
Crear un vector con 10 elementos enteros con valores aleatorios. Ordenarlos de menor a mayor. Luego invertir el vector para verlo de mayor a menor.
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=new Array(10);
  var f;
  for(f=0;f<vec.length;f++)
  {
    vec[f]=parseInt(Math.random()*1000);
  }
  vec.sort(function(v1,v2) {
    if (v1>v2)
      return 1;
    else
      return 0;
  });
  document.write('Vector ordenado en forma ascendente<br>');
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }
  vec.reverse();
  document.write('Vector ordenado en forma descendente<br>');
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
El resultado de ejecutar el programa es:
Vector ordenado en forma ascendente
32
131
329
364
488
515
860
864
919
919
Vector ordenado en forma descendente
919
919
864
860
515
488
364
329
131
32
Como vemos luego de imprimirlo en forma ordenada procedemos a llamar al método reverse() que invierte los elementos del vector (es decir el último pasa a ser primero, el anteúltimo pasa a ser segundo y así sucesivamente)

Javascript Parte XLVIII

Javascript tiene una instrucción que permite eliminar un elemento de un vector llamada delete.
Al comando delete le pasamos el nombre del vector y la posición que queremos borrar:
  delete vec[3];
Con el comando anterior estamos eliminando la componente de la posición 3 del vector. Cuando se elimina una componente no se modifica la propiedad length y el vector se convierte en no denso. Si luego tratamos de acceder a dicha posición el resultado es el valor undefined.
Problema Crear un vector de 10 elementos y almacenar valores aleatorios en el mismo. Luego borrar los elementos de las posiciones pares e imprimir el vector antes y después de borrar las componentes, inclusive tratar de acceder a las componentes que acabamos de borrar.
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[];
  var f;
  for(f=0;f<10;f++)
  {
    var valor=parseInt(Math.random()*1000);
    vec.push(valor);
  }
  document.write('Vector antes de borrar<br>');
  for(f=0;f<10;f++)
  {
    document.write(vec[f]+'<br>');
  }
  for(f=0;f<10;f=f+2)
  {
    delete vec[f];
  }
  document.write('Vector luego de borrar las posiciones pares<br>');
  for(f=0;f<10;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
Creamos y cargamos el vector con 10 enteros aleatorios:
  var vec=[];
  var f;
  for(f=0;f<10;f++)
  {
    var valor=parseInt(Math.random()*1000);
    vec.push(valor);
  }
Procedemos a borrar los elementos de las posiciones pares del vector utilizando el comando Javascript delete (veamos que dentro del for incrementamos f en 2 en cada vuelta del ciclo):
  for(f=0;f<10;f=f+2)
  {
    delete vec[f];
  }
Por último procedemos a mostrar el vector donde podemos comprobar que al tratar de acceder a componentes que se han eliminado el resultado es el valor undefined, el resultado completo de la ejecución del programa es:
Vector antes de borrar
931
354
246
876
802
980
957
307
998
640
Vector luego de borrar las posiciones pares
undefined
354
undefined
876
undefined
980
undefined
307
undefined
640

Javascript Parte XLVII

Así como el método push inserta un elemento al final del vector el método unshift inserta un elemento al principio el vector y desplaza el resto una posición.
El método shift extrae el primer elemento del vector y desplaza hacia delante el resto de elementos del vector.
Problema
Ingresar valores por teclado. Los valores menores a 100 ingresarlos al principio del vector y los mayores o iguales a 100 ingresarlos al final. Se finaliza la carga de datos al ingresar el cero. Cuando sale del do/while extraer el último valor ingresado que es el cero del vector. Imprimir el vector en la página
<html>
<head>
</head>
<body>

<script type="text/javascript">

  var vec=[];
  var f;
  var valor;
  do {
    valor=prompt('Ingresar un valor (0 para finalizar):','');
    valor=parseInt(valor);
    if (valor<100)
    {
      vec.unshift(valor);
    }
    else
    {
      vec.push(valor);
    }
  } while (valor!=0);
  vec.shift();
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

</script>

</body>
</html>
Si el valor es menor a 100 procedemos a llamar al método unshift que lo inserta al principio del vector en caso contrario se inserta al final mediante el método push:
    if (valor<100)
    {
      vec.unshift(valor);
    }
    else
    {
      vec.push(valor);
    }
Fuera del do/while procedemos a extraer el primer elemento del vector que es el cero:
  vec.shift();
Finalmente procedemos a imprimir en forma completa el vector:
  for(f=0;f<vec.length;f++)
  {
    document.write(vec[f]+'<br>');
  }

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.