1. Declaración de funciones

Como en muchos lenguajes, JavaScript permite declarar funciones. Quizá convenga recordar que una función no se ejecuta hasta que no es llamada. Es decir, podemos definir una función que use variables globales NO declaradas aún, si la llamamos una vez que dichas variables estén declaradas.

La forma de definir una función es la siguiente:

// La lista de parámetros es opcional
function nombre_funcion( lista_parametros_opcional ) {
   código;
   [return valor;] 
   // Devolver un valor tambiém es opcional
}

Pongo lista_parametros y return valor; entre corchetes porque son opcionales.

Veamos un par de detalles:

He aquí un ejemplo muy simple:

// Aqui declaro la función
function suma( a,b,c,d ) {
  return a+b+c+d;
}

// aqui la uso
la_suma=suma( 10,30,50,70 );

2. Matrices

Para crear matrices utilizamos las palabras new y Array. Estas matrices serán dinámicas, es decir, no tenemos que decirle cuántos componentes va a tener, sino que a medida que hacen falta se van añadiendo.

No obstante, podemos darle una longitud inicial de la siguiente forma:

var foo=new Array( 5 );

con ello habremos creado una matriz de 5 posiciones (desde la 0 hasta la 4) que estarán todas vacías (con un valor especial llamado undefined).

Podemos crear matrices e inicializarlas:

var foo=new Array( "Pepe","Luis",34,false );

con ello habremos creado una matriz de 4 posiciones (desde la 0 hasta la 3). La primera contiene la cadena "Pepe", la segunda la cadena "Luis", la tercera un número y la última un valor booleano.

Pero sin duda, la mejor forma de crear matrices es crearlas vacías e ir añadiendo nuevos elementos:

var foo=new Array; // foo=new Array(); foo=[];
foo[foo.length]=45;
foo.push( "Carlos" );
foo.push( "elemento", 56, 0.45 );

En el ejemplo anterior hemos hecho uso del método push, que permite añadir elementos al vector, y también de la propiedad length que tienen TODAS las matrices en JavaScript y que indica cuántos elementos tiene la matriz.

3. Objetos

Crear un nuevo objeto implica dotarlo de propiedades y métodos, es decir, crear una especie de clase de la que luego se puedan hacer instancias. Ha de tenerse en cuenta que los objetos no se pueden destruir, sino que perviven mientras esté el documento cargado.

Para crear un objeto, tenemos que crear una función constructor. Por ejemplo, supongamos que queremos crear el objeto ordenador con las propiedades microprocesador, velocidad, y sistema operativo. Tendríamos que crear una función de la siguiente forma:

// No existen clases... pero podemos crear "constructores"
function Casa( p_ciudad, p_plantas, p_habitaciones, p_banios ) {
  this.ciudad=p_ciudad;
  this.plantas=p_plantas;
  this.habitaciones=p_habitaciones;
  this.banios=p_banios;
} // function Casa

Como vemos el nombre de la función coincide con el nombre del objeto que deseamos crear.

Posteriormente podremos crear instancias de este objeto llamando a la función, anteponiendo la partícula new, es decir:

var casa1=new Casa( "Jaen", 1, 3, 2); // En Jaen, 1 planta, 3 habitaciones, 2 baños
var casa2=new Casa( "Huelva", 2, 4, 3 ); // En Huelva, 2 plantas, 4 habitaciones, 3 baños 

En cualquier parte del código, no necesariamente en la función constructor, podemos añadir de forma dinámica nuevas propiedades a un objeto. Podemos hacerlo de dos formas. La primera es añadírsela a una sola instancia, por ejemplo:

casa2.patio="60m2";

O bien añadírselo al objeto en general (y por tanto a todas las instancias), para lo cual se ha de incluir la palabra reservada prototype:

Casa.prototype.balcon=NUL

Como se ha dicho, además de propiedades, los objetos tienen métodos. Para dotar de métodos a un objeto tenemos las mismas tres opciones que con las propiedades: 1) ponerlo en la declaración del objeto, 2) añadirlo a una sola instancia, y 3) añadirlo al objeto en general.

Para ver cómo se hace vamos a añadir al objeto Casa un método que se llame concatena devuelva todas las propiedades del objeto concatenadas:

function visualiza_casa() {
 var cadena="Situada en  "+this.ciudad+"\n"+
            "Tiene "+this.velocidad+" plantas\n"+
            "Con "+this.habitaciones+" habitaciones\n"+
            "Y "+this.banios+" baños";
} // function visualiza

Lo anterior sirve para declarar la función que visualiza, ahora la declaración de la función que construye el objeto quedaría de la siguiente forma:

function Casa( p_ciudad, p_plantas, p_habitaciones, p_banios ) {
  this.ciudad=p_ciudad;
  this.plantas=p_plantas;
  this.habitaciones=p_habitaciones;
  this.banios=p_banios;
  this.concatena=visualiza_casa;
} // function Casa

Nótese que NO escribimos:

this.concatena=visualiza_casa();

Si lo hubiéramos hecho, se habría asignado a this.concatena el resultado de ejecutar la función visualiza_casa y no es eso lo que queremos.

Como puede apreciarse, la palabra reservada this juega un papel muy importante dado que hace referencia a la instancia del objeto en sí y es lo que hemos de usar para acceder a las propiedades del objeto.

También queda de manifiesto que el método puede llamarse de una forma y la función que lo implementa de otra.

Para usar un método de un objeto solo hemos de poner:

  variable_objeto.metodo();

Por ejemplo:

cadena=casa1.concatena();

4. El formato JSON

El formato JSON se ha convertido en un mecanismo bastante simple y eficiente de describir y transferir datos entre dos aplicaciones.

Está basado en la capacidad que tiene Javascript para describir de forma muy eficiente literales de vectores y objetos. Además, dichos literales pueden recibirse en forma de cadena desde un servidor (mediante AJAX, o a través de la URL de la página) y convertirse de una forma muy rápida en objetosy vectores dentro de nuestro programa

Los literales de vector se definen usando los corchetes:[], como en el siguiente ejemplo:

<script>
 var personas=["Adela", "Benjamín", "Carlos", "Daniela", "Enrique"];
</script>

Por su parte, los literales de objeto se definen utilizando llaves y, posteriormente, dando valor a cada uno de sus atributos:

<script>
 var autor= {
   nombre": "Víctor Manuel",
   ""apellidos": "Rivas Santos",
   "telefono": 953212344,
   "año": 2014,
 }
</script>

La definición de métodos también está permitida cuando describimos un objeto, como en el siguiente caso:

<script>
  // Defino primero el método
  function nombreTfno() {
     console.log( this.nombre+" "+this.telefono );
  }
  var autor= {
   "nombre": "Víctor Manuel",
   "apellidos": "Rivas Santos",
   "telefono": 953212344,
   "año": 2014,
   "showConsole": function() {
      console.log( "Por "+this.nombre+" "+this.apellidos+". (C) "+this["año"] );
   },
   "nombre_telefono": nombreTfno // Ojo: Sin poner los paréntesis ()
 }
</script>

Por supuesto, también podemos hacer combinaciones de ambos, por ejemplo, definir un vector de objetos:

<script>
 var agenda= [
  { "nombre": "Ana", "telefono": 123456789 },
  { "nombre": "Luis", "telefono": 5555353 },
  { "nombre": "Angel", "telefono": 87648756 },
  { "nombre": "Daniel", "telefono": 7845647856 },
  { "nombre": "Jose", "telefono": 98347594875 }
 ]
</script>

Así como definir objetos que internamente almacenen vectores:

<script>
 var contacto={
    "nombre": "Luis",
    "apellidos": "Perez",
    "telefonos": [121287, 232343, 34343434]
}
</script>

O, en general, cualquier otra combinación que nos haga falta. Como en el siguiente caso en el cual, "rizamos el rizo", como suele decirse:

<script>
var contacto={
    nombre: "Luis",
    apellidos: "Perez",
    telefonos: [
        { desc: "casa", numero: "95x232938" }, 
        { desc: "móvil", numero: "6x8374837" }, 
        { desc: "trabajo", numero: "34343434" }
    ]
}
</script>

Algunas expresiones válidas para acceder a los datos almcenados en contacto serían:

contacto.nombre  // Luis
contacto.telefonos.length // 3
contacto.telefonos[1].desc // móvil 

Nota: En el ejemplo anterior hemos omitido las comillas para los atributos de los objetos; es posible hacerlo en Javascript, sin que falle el programa.

Como se ha indicado, una de las ventajas de JSON es que posibilita el intercambio de información entre dos aplicaciones cualquiera, y por supuesto en entornos cliente /servidor. De esta forma, podemos enviar a una página web (mediante AJAX o quizá en la URL) una cadena describiendo literales en formato JSON, los cuales pueden ser DIRECTAMENTE incorporados a nuestro programa en Javascript para trabajar con ellos.

Existen dos formas de incoporar una cadena que contiene la descripción de un literal en formato JSON. La primera de ellas consiste en usar la función eval, como en el siguiente ejemplo:

var cadena="{'nombre': 'Víctor Rivas'}"; // Nos llegaría desde un servidor, por ejemplo
var autor=eval("("+cadena+")" );

Como puede verse, es necesario añadir unos paréntesis a la expresión para que pueda ser evaluada correctamente.

No obstante, existe una biblioteca nativa de Javascript que permite codificar vectores y objetos en forma de cadenas, y descodificar una cadena al correspondiente objeto o vector. Es la biblioteca JSON, en la cual encontramos las funciones stringify y parse.

El siguiente ejemplo muestra el uso de ambos.

// Defino primero el método para no tener que repetir el código
function show() {
  return this.programa+": "+this.horario;
}
var parrilla=[
  { programa: "Telediario", horario: "21:00 - 21:45", mostrar: show },
  { programa: "Velvet", horario: "22:10 - 00:15", mostrar: show }
]

var cadena=JSON.stringify( parrilla );
// cadena es 
// "[{"programa":"Telediario","horario":"21:00 - 21:45"},{"programa":"Velvet","horario":"22:10 - 00:15"}]"
var objeto=JSON.parse( cadena );
// objeto contendría los mismos elementos que parrilla