Saltear al contenido principal

Curso de JavaScript (y jQuery)

Introducción y objetivos

JavaScript toma su sintaxis de los lenguajes de programación más conocidos, fundamentalmente C, aunque también algo de Pascal. Esto en la práctica significa que:

  • JavaScript es sensible al contexto, o sea, que distingue mayúsculas de minúsculas.
  • Es un lenguaje orientado a eventos y basado en objetos (que no es lo mismo que orientado a objetos). Lo anterior significa que:
    • Existen objetos …

    • … que tienen propiedades y métodos, …
    • … que sufren eventos, y …
    • … que pueden definir qué acción realizar cuando ocurre el evento.

En este tema vamos a ver cuál es la sintaxis básica de Javascript para definir variables, así como las sintaxis de sus sentencias y de la declaración de funciones. Adicionalmente, veremos de qué forma se pueden definir nuestros propios objetos y su utilización en vectores o matrices.

Los objetivos por tanto son los siguientes:

  • Conocer la forma en que se declaran y utilizan variables
  • Saber utilizar las sentencias de asignación, lectura y escritura
  • Saber utilizar las sentencias selectivas e iterativas.
  • Conocer la sintaxis que permite declarar nuevas funciones en Javascript
  • Utilizar el mecanismo de declaración de nuevos objetos que incluye Javascript: declarar objetos con atributos y métodos
  • Saber definir variables que almacenen conjuntos de elementos en forma de vectores o matrices.
  • Almacenar valores en una matriz y recorrerla consultando o actualizando sus datos.

2.1. Las variables

Como en la mayoría de los lenguajes de programación, Javascript utiliza una serie de instrucciones para operar sobre ciertos datos. Los datos pueden representarse de forma explícita en una instrucción,
como por ejemplo:

document.write( “Hola Mundo!” )

document.write( 3+5 );

O bien ser almacenados en una variable y posteriormente usar el contenido de dicha variable, como en el siguiente trozo de código:

var texto = “Hola Mundo!”

var anioActual = 2017

var anioNacimiento = 1985

document.write( texto )

document.write( anioActual – anioNacimiento )

document.write es una especie de print por pantalla y nos permite escribir en nuestra página web textos/números, valores de variables, resultados de operaciones o funciones o elementos HTML, que además pueden estar concatenados. Se trata del método write del objeto document (ver apartado 3.7). También puedes ver una explicación sobre document.write en nuestro curso de Aprende a Pogramar (con (JS).

Podemos trabajar con los datos más habituales tales como números enteros, números reales, cadenas de caracteres y valores lógicos o booleanos. No obstante, en Javascript NO hay tipificación de las variables, ni tampoco constantes. Por ende, tampoco se pueden definir nuevos tipos de variables, aunque sí nuevos tipos de objetos (como se verá más adelante)

Para usar una variable, hemos de empezar por darle un valor con el signo =:

miNumero=15;

miCadena=”Hola, ¿qué tal?”;

Es habitual utilizar la palabra clave var para declarar una variable, aunque no es obligatorio salvo cuando queremos restringir su alcance dentro de una función, como veremos más adelante.

Podríamos haber escrito igualmente:

var miNumero=15;

var miCadena=”Hola, ¿qué tal?”;

Por cierto, el punto y coma del final NO es realmente necesario si se separan las instrucciones en líneas distintas, como suele ser el caso, aunque siempre es recomendable incluirlo. Si deseamos escribir varias
instrucciones en la misma línea debemos usar el ; para separarlas, así que es buena práctica incluirlas siempre para evitar errores y delimitar mejor el código.

Dado que lo que contendrán son datos, las variables también pueden almacenar:

  • números enteros
  • números reales
  • cadenas (las cadenas se escriben entre comillas dobles o
    simples, es indiferente)
  • valores booleanos (es decir, los valores true o false)
  • objetos
  • matrices (de cualquiera de los datos descritos).

El tipo de la variable será el del valor que en cada momento le hayamos asignado. En los ejemplos anteriores miNumero es de tipo numérico (porque es un número entero), y miCadena lo es de tipo cadena.

En Javascript se intenta hacer conversiones de tipo siempre que haga falta. Así por ejemplo, si escribimos la siguiente sentencia:

miConcatenacion=miNumero+miCadena

no obtendremos ningún error debido a tipos no compatibles ni nada de eso, sino que concatenará miNumero y miCadena cual si de dos cadenas se tratara.

Es más, si escribiéramos algo como;

miDato=”Esto es una cadena”;

miDato=15*2;

miDato=miDato*3;

el resultado final de la variable miDato es 90. Es decir, también convierte cadenas a números cuando hace falta.

Para poder utilizar una variable debemos saber cuál es el ámbito de validez de la misma, es decir, las porciones del programa en las que esa variable está definida. Hay que tener en cuenta que un programa en Javascript está compuesto por muchas porciones de código, muchas de ellas recogidas en forma de subprogramas o funciones.

Para Javascript, el ámbito de una variable es siempre el más amplio posible. Es decir, si comenzamos a usar una variable fuera de cualquier función (en lo que llamaríamos el “programa principal”), desde ese
momento estará disponible dentro de cualquier función como variable global.

En el siguiente ejemplo, la función suma_20_a_edad modifica la variable edad sumándole el número 20, pero sin que la variable se le pase como parámetro, sino que se usa como variable global (ya que la variable en sí, la variable edad, está siendo definida fuera de la función).

edad = 27; // Defino el valor de la variable

suma_20_a_edad(); // llamada a función en que modificará dicha variable

Esto puede causar problemas de efectos laterales y podría darse el caso de que modificáramos una variable global en una función pensando que solo estamos cambiando una variable local a dicha función, y todo por el hecho de haberles dado a ambas el mismo nombre.

Para evitar esto, podemos ponerle la palabra clave var antes de usar por primera vez la variable en la función, para indicar que dicha variable es local a la función en que se está usando.

Veamos un ejemplo:

function modifica_edad() {

edad=edad+100;

}

function no_modifica_edad() {

var edad=edad+100;

}

edad = 30;

modifica_edad();

no_modifica_edad();

En este ejemplo, tras llamar a modifica_edad() la variable global edad pasa de valer 30 a valer 130. Sin embargo, tras llamar a no_modifica_edad sigue con el valor 130.

Como se puede observar NO se le ha puesto la palabra var a la variable global dado que, en efecto, no es necesario pues va a ser global de cualquier forma.

En el curso de “Aprender a Programar (con JS)” puedes ver lo que explicamos sobre las variables en JavaScript, incluyendo las normas que deben utilizarse para sus nombres.

2.2. Sentencias

Los lenguajes de programación suelen definir tres tipos de sentencias o instrucciones:

  • Secuenciales
  • Selectivas
  • Iterativas

Javascript también lo hace. Además, la sintaxis de sus sentencias es muy similar a la sintaxis del lenguaje C.

2.2. Sentencias

2.2.1. Sentencias Secuenciales

Podemos describir tres sentencias secuenciales en Javascript: asignación, escritura y lectura.

Hemos visto anteriormente que la asignación se realiza con el símbolo =, es decir:

variable=expresion

Esta sentencia, por si misma, no ejecuta ninguna acción “visible” para el usuario de nuestra página web, pero es fundamental para que nuestros programas puedan ir haciendo poco a su trabajo, realizando cálculos que se van almacenando en las variables.

Si queremos interactuar con el usuario, habremos de utilizar las otras dos sentencias secuenciales: la escritura y la lectura.

Por simplificar un poco, la sentencia de escritura podemos considerar que es write. En realidad, debemos decir que es document.write ya que es un método de un objeto que se llama document. Como hemos dicho, este es uno de los mecanismos que podemos usar para escribir cosas desde Javascript para que se puedan ver a través del navegador. Sin embargo, actualmente el mecanismo que se ha impuesto como estándar es el de utilizar capas y su propiedad innerHTML, como también veremos al estudiar el objeto document.

Mostramos a continuación algunos ejemplos en los que se usa la asignación y la escritura en un programa de Javascript.

document.write( “<h2>Ejemplo de uso de sentencias de escritura</h2>” )

document.write( “<p>” )

anioActual=2010

document.write( “Estamos en “, anioActual )

anioNacimiento=1981

document.write( ” por lo que si usted nació en “, anioNacimiento )

document.write( ” su edad es de “, anioActual-anioNacimiento, ” años” )

document.write( “</p>” )

La sentencia de lectura permite al usuario darle datos al programa, o si se prefiere, permite al programa preguntarle datos al usuario. En Javascript esta asignatura no existe como tal, aunque el objeto window tiene un método llamado prompt que se puede usar para tales menesteres. Lo normal, no obstante, es usar elementos de formularios (especialmente campos text) para solicitar datos al usuario.

Hemos modificado el ejemplo anterior para que calcule automáticamente el año en que estamos y para que le pregunte al usuario en qué año nació:

document.write( “<h2>Ejemplo de uso de sentencias de escritura</h2>” )

document.write( “<p>” )

fecha=new Date()

anioActual=fecha.getFullYear()

anioNacimiento=prompt( “¿En qué año nació usted?”, “” ) * 1

document.write( “Estamos en “, anioActual )

document.write( ” por lo que si usted nació en “, anioNacimiento )

document.write( ” su edad es de “, anioActual-anioNacimiento, ” años” )

document.write( “</p>” )

Puedes ver el funcionamiento del método prompt en el apartado 3.2. También puedes consultarlo aquí: http://www.digitallearning.es/intro-programacion-js/prompt.html

En este último ejemplo hemos utilizado el objeto Date. Puedes ver una explicación del mismo y de sus métodos aquí: http://www.digitallearning.es/intro-programacion-js/metodos-date.html

2.2. Sentencias

2.2.2. Sentencias Condicionales

Las sentencias secuenciales permiten evaluar una condición y ejecutar un grupo de instrucciones si la condición resulta ser verdadera, y otro grupo de instrucciones distinto si la condición resulta ser falsa. A este tipo de sentencias se les suele denominar if…then…else… porque tienen la siguiente forma:

if ( condicion ) {

sentencias_true;

} else {

sentencias_false;

}

Por ejemplo, podemos comprobar un usuario es o no mayor de edad:

edad=prompt( “Indique su edad, por favor”, “” )

if ( edad < 18 ) {

document.write( “Usted es un menor de edad.<br>” )

document.write( “No olvide adjuntar el documento de autorización.” )

} else {

document.write( “Usted es mayor de edad.<br>” )

document.write( “No olvide adjuntar fotocopia del DNI.” )

}

Existen casos en los que deseamos comprobar para una misma variable distintos valores; en esas ocasiones conviene utilizar otra sentencia llamada switch que opera de la siguiente forma:

switch( variable ) {

case valor :

case valor : { sentencias; break; }

case valor :

case valor : { sentencias; break; }

default: { sentencias; }

}

Por ejemplo:

universidad=prompt( “Indique su Universidad andaluza de origen: “, “” )

switch( universidad ) {

case “Huelva” :

case “Sevilla” :

case “Cadiz” : { document.write (“No convalidan créditos” ) }; break;

case “Malaga” :

case “Cordoba”: { document.write (“Convalidan 50% de créditos” ) }; break;

case “Jaen” :

case “Almeria”:

case “Granada”: { document.write (“Convalidan 70% de créditos” ) }; break;

default: { document.write( “No reconozco la Universidad que usted indica” ) }

}

2.2.3. Sentencias Iterativas

Finalmente, Javascript permite ejecutar varias veces un mismo trozo de código, haciendo más fácil repetir una misma tarea escribiéndola una sola vez.

Las sentencias que incorporar para hacer los denominados bucles son:

while( condicion ) {

sentencias;

}

// *****************************

do {

sentencias;

} while ( condicion );

// *****************************

for( inicializacion; condición; incremento ) {

sentencias;

}

A modo de ejemplo, realizamos un programa que escribe en pantalla la tabla de multiplicar del 17, aunque en vez de multiplicar hasta 10, lo hace hasta 50.

document.write( “<h2>Tabla de multiplicar del 17</h2>” )

cont=1;

while( cont<=50 ) {

document.write( 17, “*”, cont, “=” )

document.write( 17*cont )

document.write( “<BR>” )

cont=cont+1;

}

// OTRA FORMA DE HACERLO

for( cont=1; cont<=50; cont=cont+1 ) {

document.write( 17, “*”, cont, “=” )

document.write( 17*cont )

document.write( “<BR>” )

}

2.2. Sentencias

2.2.4. Incrementos y operaciones con variables

Como en otros lenguajes de sintaxis parecida, se pueden realizar pre-incrementos, post-incrementos, hacer uso del operador ternario, etc.

variable++; ++variable; variable–; –variable;

variable+=valor; variable-=valor; variable*=valor; variable/=valor;

variable=(condicion)?valor_true:valor_false;

2.2.5. Comentarios

Los comentarios se realizan como en el lenguaje C, es decir:

  • Con // obtendremos comentarios hasta el final de la línea.
  • Con /* …. */ obtendremos comentarios de varias líneas.

2.3. 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:

function nombre_funcion( lista_parametros ) {

código;

return valor;

}

Tanto lista_parametros como return valor son opcionales así que, dependiendo de la función que en cada momento estemos declarando habrá que poner alguno de ellos, los dos o ninguno.

Veamos un par de detalles:

  • En primer lugar, la palabra function debe estar siempre presente. No existen procedure, solamente funciones.
  • En segundo lugar, la lista de parámetros es solo una lista de nombres de variables separadas por comas, sin poner ni del tipo que son, ni nada de eso.
  • En tercer lugar, no existe paso de parámetros por variable o referencia, únicamente por valor, así que hemos de olvidarnos de hacer procedimientos/funciones que modifiquen varias variables a no ser que éstas sean globales.
  • Por último, la función puede devolver un valor, que es para lo que sirve la sentencia return

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 );

el_nombre=suma( “Luis”, “Angel”, “Perez”, “Lopez” )

Las funciones suelen declararse en la parte <HEAD> de una página web, o incluso en ficheros aparte, ficheros con extensión .js, como ya vimos. De esta forma, al ponerse al principio de la página web, conseguimos que todas las funciones estén cargadas en memoria antes de que se haga uso de ellas, y no se produzca un error al llamar a una función que aún no ha sido declarada.

2.4. Vectores o matrices

De forma muy simplificada, podemos decir que las matrices o vectores son estructuras de datos (es decir, variables) que permiten almacenar muchos datos dentro de ellas. Una variable que sólo puede almacenar un valor en un momento dado es una estructura de datos simple; sin embargo, una variable que puede almacenar muchos valores simultáneamente se denomina una estructura de datos compuesta, cual es el caso de las matrices.

En Javasctript, 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.

Así, podemos inicializar una matriz vacía con:

var miMatrizA=new Array;

No obstante, podemos crear matrices e insertarle datos simultáneamente:

var miMatrizB=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 el número 34 y la última el valor booleano false.

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

var miMatrizC=new Array;

miMatrizC[miMatrizC.length]=45;

miMatrizC[miMatrizC.length]=”Carlos”;

miMatrizC[miMatrizC.length]=3+4;

miMatrizC.push( “Luis” );

miMatrizC.push( true );

En el ejemplo anterior hemos añadido elementos a la matriz miMatrizC usando dos métodos; por un lado, hemos usado la propiedad length que tienen TODAS las matrices en Javascript y que indica cuántos elementos tiene la matriz. Por otro lado, hemos usado el método push que también toda matrz tiene.

Una de las grandes ventajas que nos ofrecen las matrices es la posibilidad de recorrer todos sus elementos utilizando bucles. Por ejemplo, podemos mostrar todos los valores de una matriz con un simple bucle de tipo for:

for( i=0; i<miMatrizC.length; ++i ) {

document.write( miMatrizC[i], “<br>” );

}

2.5 Objetos

Javascript no es un lenguaje orientado a objetos, pero sí basado en objetos. No permite definir clases, ni utilizar herencia, etc. Pero sí podemos crear objetos y utilizarlos con la sintaxis habitual.

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 Casa con las propiedades ciudad, número de plantas, número de habitaciones y número de cuartos de baño. Tendríamos que crear una función de la siguiente forma:

// Declaración de la función constructora de la “clase” Casa

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, el cual devuelve todas las propiedades del objeto concatenadas:

// Función que visualiza todas las propiedades de una casa. Aún NO ES un método de Casa

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”;

return cadena;

} // 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.

Una alternativa para no tener que declarar una función auxiliar (como es visualiza_casa en este caso) es definirle al método una función “sin nombre” 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=function() {

var cadena=”Situada en “+this.ciudad+”\n”+

“Tiene “+this.velocidad+” plantas\n”+

“Con “+this.habitaciones+” habitaciones\n”+

“Y “+this.banios+” baños”;

return cadena;

}

} // function Casa

Cada objeto de tipo Casa definido de esta segunda forma sigue teniendo un método llamado concatena que hace exactamente lo mismo que antes.

Como puede apreciarse, en la declaración de métodos 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.nombre_del_metodo( parametros );

Por ejemplo:

cadena=casa1.concatena();

2.6. Ejemplo de código Javascript

A continuación, mostramos un ejemplo completo en el que usamos Javascript para generar de forma aleatoria los resultados de una jornada de fútbol de la primera división española (el orden de los equipos es alfabético).

En este ejemplo, usamos tanto sentencias secuenciales como iterativas y selectivas. También mostramos el uso de funciones, objetos y matrices. El código incluye comentarios para poder entender qué se va realizando.

 

2.7. Sumario

Hemos realizado un breve resumen de la sintaxis básica de Javascript: creación de variables, ejecución de instrucciones, declaración de funciones, objetos y matrices.

El conjunto completo de bibliotecas y funciones que posee Javascript exceden con mucho la extensión de este curso. Puede encontrarse una completa Guía de Referencia en http://www.w3schools.com/jsref/default.asp.

En cualquier caso, la dificultad a la hora de programar tanto en Javascript como en cualquier otro lenguaje no radica tanto en el conocimiento de sus instrucciones como en la forma en que las usamos para construir nuestros programas. Por lo general, el conjunto de instrucciones es pequeño, pero su uso combinado en el orden correcto permite hacer las más variadas aplicaciones. Sólo la práctica de la programación permite adquirir esta capacidad.

Volver arriba