Introducción a JavaScript

Computación Web (2025/26)

Jesús Arias Fisteus

Variables


var n = 1;  // variable global
var sumDoubled = function(m) {
    var mDoubled = 2 * m;  // variable local
    n += mDoubled;
}

sumDoubled(2);
n;                // 5
          
Las variables pueden declararse con la palabra clave var. Si una variable se declara fuera de cualquier función, es una variable global.
Las variables declaradas con la palabra clave var dentro de una función son locales a esa función. Su ámbito es toda la función, incluso si su declaración está anidada dentro de otros bloques (como if, for, etc.).
Las funciones pueden asignarse a variables. El nombre de la variable se usa luego para llamar a la función.
Llama a la función sumDoubled, pasando el número 2 como argumento.

Variables


let sum_up_to = function(n) {
    let total = 0;
    for (let i = 1; i <= n; i++) {
        total += i;
    }
    return total;
}
          
La palabra clave let se utiliza para declarar variables con ámbito de bloque. Esto significa que la variable i solo es accesible dentro del bloque (en este caso, el bucle for) donde se define. Si se hubiera declarado con var en su lugar, habría sido accesible en toda la función, no solo en el código dentro del bucle.

Sentencias de control

  • if, switch
  • for, while, do while
  • return, break, continue

Condicionales y operadores de comparación


if (command === "create") {
    // ...
}

if (command !== "remove") {
    // ...
}

if (num >= 7) {
    // ...
}
          
=== comprueba la igualdad sin conversión de tipos. Se recomienda usarlo en lugar de == a menos que sepas exactamente lo que estás haciendo.
!== comprueba la desigualdad sin conversión de tipos. Se recomienda usarlo en lugar de != a menos que sepas exactamente lo que estás haciendo.

Operadores lógicos


if (command === "create" || command === "remove") {
    // ...
}

if (command === "remove" && num > 7) {
    // ...
}

let a = false;
while (!a) {
    // ...
}
          
|| es el operador de o lógico.
&& es el operador de y lógico.
! es el operador de negación lógica.
Nótese que false y true se escriben en minúsculas.

Bucles


let count = 0;
while (count < 10) {
    console.log(count);
    count++;
}

for (let count = 0; count < 10; count++) {
    console.log(count);
}

let person = {fname: "Lisa", lname: "Simpson", age: 25};
for (let x in person) {
    console.log(person[x]);
}
for (let value of Object.values(person)) {
    console.log(value);
}
          
El bucle while se repite mientras la condición sea verdadera.
Inicialización de la variable del bucle.
Condición del bucle. Se evalúa antes de cada iteración. La iteración se detiene cuando deja de ser verdadera.
Actualización de la variable del bucle. Se ejecuta al final de cada iteración.
El bucle for...in itera sobre las propiedades enumerables de un objeto. En este caso, itera sobre los nombres de las propiedades del objeto person. Si se usara con un array, iteraría sobre los índices del array, no sobre los valores.
Nombre de la propiedad.
Valor de la propiedad.
El bucle for...of itera sobre objetos iterables (como arrays). Aquí usamos el método estático Object.values para obtener un array con los valores de las propiedades del objeto person. El bucle for...of itera luego sobre los valores de ese array.

Tipos de datos

  • Tipos simples:
    • Números
    • Cadenas de texto
    • Booleanos
  • Objetos:
    • Arrays
    • Funciones
    • Objetos

Tipos de datos


let count = 0;
let word = "University";
let active = true;
let square = function(n) {
    return n * n;
};
let color = {
    r: 30,
    g: 255,
    b: 128,
    luminosity: function() {
        return 0.21 * this.r + 0.72 * this.g + 0.07 * this.b;
    }
};
          
Un número.
Una cadena de texto.
Un booleano.
Una función que recibe un argumento.
Un objeto con cuatro propiedades.
Un método (una función que es propiedad de un objeto).
Dentro de un método, this se refiere al objeto del que el método es propiedad.

Objetos


let emptyObject = {};

let student = {
    "first-name": "Lisa",
    "last-name": "Simpson"
};
student["first-name"]     // "Lisa"
student["middle-name"]    // undefined
student["FIRST-NAME"]     // undefined
          
Un objeto vacío (sin propiedades).
Se evalúa al valor de la propiedad first-name del objeto student.
Si la propiedad no existe, el resultado es undefined. No se produce ningún error.
Los nombres de las propiedades distinguen entre mayúsculas y minúsculas.

Objetos


let book = {
    title: "El ingenioso hidalgo Don Quijote de la Mancha",
    year: 1605,
    author: {
        name: "Miguel",
        surname: "de Cervantes Saavedra",
        birthYear: 1547
    }
};
book.year;               // 1605
book.author.name;        // "Miguel"
          
Las propiedades de un objeto pueden ser a su vez objetos. Es decir, los objetos pueden anidarse.
La notación de punto puede utilizarse para acceder a propiedades cuyos nombres son identificadores válidos (comienzan por una letra, _ o $, y contienen solo letras, dígitos, _ y $).

Objetos


book.author['birthPlace'] = 'Alcalá de Henares'
book.originalLanguage = 'Spanish';
          
Si la propiedad no existe en el objeto, se crea. Si existe, se actualiza su valor.

Objetos

Los objetos se manipulan por referencia (como en Java)


let x = book;
x.genre = 'novel';
let genre = book.genre;

let a = {}, b = {}, c = {};

a = b = c = {};
          
La variable x es una referencia al mismo objeto al cual la variable book hace referencia.
Al añadir una propiedad al objeto a través de x, ésta también estará disponible mediante book, ya que ambas variables hacen referencia al mismo objeto.
Las variables a, b y c hacen referencia a tres objetos vacíos distintos.
Las tres variables hacen ahora referencia al mismo objeto vacío.

Funciones


let add = function(a, b) {
    return a + b;
};

let sum = add(3, 4);    // sum is 7
          

Funciones


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

let sum = add(3, 4);    // sum is 7
          

Métodos


let color = {
    r: 30,
    g: 255,
    b: 128,
    luminosity: function() {
        return 0.21 * this.r + 0.72 * this.g + 0.07 * this.b;
    }
};
color.luminosity();  // 198.86
          

Métodos


let color = {
    r: 30,
    g: 255,
    b: 128,
    luminosity() {
        return 0.21 * this.r + 0.72 * this.g + 0.07 * this.b;
    }
};
color.luminosity();  // 198.86
          

Constructores


let Color = function(r, g, b) {
    // Create the properties of the object
    this.r = r;
    this.g = g;
    this.b = b;

    // Create the methods of the object
    this.luminosity = function() {
        return Math.round(0.21 * this.r + 0.72 * this.g
                          + 0.07 * this.b);
    }

    this.toGrayScale = function() {
      let a = this.luminosity();
      return new Color(a, a, a);
  }
}
          
Un constructor es una función que inicializa un nuevo objeto de un tipo dado. Por convención, los nombres de los constructores comienzan con mayúscula.
Dentro de un constructor, this hace referencia al nuevo objeto que se está creando. Aquí, se crea una nueva propiedad del objeto a partir de un parámetro del constructor.
El operador new crea un nuevo objeto y llama al constructor para inicializarlo.

Constructores


let red = new Color(255, 0, 0);
red.luminosity();             // 54
let gray = red.toGrayScale(); // Color (r: 54, g: 54, b: 54)
          
El operador new crea un nuevo objeto y llama al constructor para inicializarlo.
Llama al método luminosity del objeto red.
Llama al método toGrayScale del objeto red. Internamente, crea y devuelve un nuevo objeto de tipo Color (ver la definición del método en la diapositiva anterior).

Clases (a partir de ECMAScript 6)


class Color {
    constructor(r, g, b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    get luminosity() {
        return Math.round(0.21 * this.r + 0.72 * this.g
                          + 0.07 * this.b);
    }

    toGrayScale() {
        let a = this.luminosity;
        return new Color(a, a, a);
    }
}
          
Una clase se define con la palabra clave class. Por convención, los nombres de las clases comienzan con mayúscula. Esto es azúcar sintáctico sobre el mecanismo de función constructora que hemos visto antes.
El constructor de la clase se define con un método llamado constructor.
Un método getter se define con la palabra clave get. Puede llamarse sin paréntesis, como si fuera una propiedad.

Constructores


let red = new Color(255, 0, 0);
red.luminosity;               // 54
let gray = red.toGrayScale(); // Color (r: 54, g: 54, b: 54)
          
Los objetos se crean de la misma manera tanto si se definen con la sintaxis class como con la sintaxis tradicional de función constructora.
Llama al método getter luminosity del objeto red. Nótese que no se usan paréntesis porque es un método getter.

Excepciones


let add = function (a, b) {
    if (typeof a !== 'number' || typeof b !== 'number') {
        throw {
            name: 'TypeError',
            message: 'add needs numbers'
        };
    }
    return a + b;
}

try {
    add("seven");
} catch (e) {
    console.log('Ups!');
    console.log(e.name + ': ' + e.message);
}
          
Se lanza una excepción con la sentencia throw. Puede ser cualquier valor de JavaScript (objeto, cadena de texto, número, etc.).
El código que puede lanzar una excepción se coloca dentro de un bloque try.
Si se lanza una excepción dentro del bloque try, el control se transfiere al bloque catch correspondiente. El valor de la excepción se asigna a la variable especificada entre paréntesis después de la palabra clave catch.

Arrays


let empty = [];
let letters = ['A', 'B', 'C', 'D', 'E', 'F'];

empty[1]          // undefined
letters[1]        // 'B'

empty.length      // 0
letters.length    // 6
          
Un array vacío.
Un array con seis elementos.
Acceso a un elemento del array. Si el índice está fuera de los límites, el resultado es undefined en lugar de producir un error.
El índice 1 accede al segundo elemento del array, ya que los índices comienzan en 0.
La propiedad length de un array contiene el número de elementos del array.

Arrays


letters.length = 3;
// letters is ['A', 'B', 'C']

letters[letters.length] = 'Y';
// letters is ['A', 'B', 'C', 'Y']

letters.push('Z');
// letters is ['A', 'B', 'C', 'Y', 'Z']

delete letters[2];
// letters is ['A', 'B', undefined, 'Y', 'Z']

letters.splice(2, 1);
// letters is ['A', 'B', 'Y', 'Z']
          
La propiedad length del array puede modificarse. Si se establece a un valor menor, el array se trunca.
Se puede añadir un nuevo elemento al final del array asignando un valor al elemento en el índice length.
El método push es otra forma de añadir un nuevo elemento al final del array.
El operador delete elimina un elemento del array, pero no cambia su longitud. El elemento eliminado pasa a ser undefined.
El método splice elimina elementos de un array y modifica su longitud. El primer argumento es el índice del primer elemento a eliminar, y el segundo argumento es el número de elementos a eliminar. En este ejemplo, elimina un elemento en el índice 2 (el tercer elemento).

Client-side JavaScript

Client-side JavaScript

  • El término client-side se refiere al entorno de ejecución de código JavaScript proporcionado por los navegadores web.
  • Este entorno lo conforman las APIs de JavaScript definidas por HTML5 y otros estándares relacionados, e implementadas por los navegadores.

Client-side JavaScript

  • Client-side JavaScript hace interactivo el documento HTML mediante, principalmente:
    • Manejadores de eventos: código a ejecutar cuando se cargue o cierre el documento, el usuario interaccione con sus elementos, etc.
    • Modificación dinámica del documento: mediante el API DOM, principalmente, el programa JavaScript puede modificar el documento, y el navegador muestra inmediatamente los cambios.

Inclusión de JavaScript en HTML


<!-- directamente con el elemento script
     (en la cabecera o en el cuerpo del documento) -->
<script type="text/javascript">
let d = new Date();
document.write(d.toLocaleString());
</script>

<!-- from an external resource -->
<script src="scripts/util.js" type="text/javascript"></script>

<!-- from an HTML event handler -->
<input type="button" value="Change" onclick="changeName()">
<p onmouseover="showHelp('p1')">...</p>
          

Cargar el código JavaScript al fondo del documento permite presentar más rápidamente la página (se cargan antes las imágenes, hojas CSS, etc.)

JQuery

Hola Mundo con JQuery


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Mi primera página jQuery</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script type="text/javascript">
      $(function() {
          console.log("ready!");
      });
    </script>
  </head>
  <body>
    <p>Hello World!</p>
  </body>
</html>
          

Abrir ejemplo

Código de inicialización


// Se ejecuta el código de inicialización cuando el árbol
// esté cargado
$(document).ready(function() {
    console.log("ready!");
});

// Forma compacta equivalente a lo anterior
$(function() {
    console.log("ready!");
});
          
El código dentro de la función se ejecuta cuando el árbol DOM del documento está completamente cargado. Este es el lugar adecuado para poner código de inicialización que necesite acceder a elementos del documento, ya que, hasta entonces, no se garantiza que los elementos existan.

Encadenamiento de métodos


var title = $("<h1>¡Hola!</h1>");
title.css("font-family", "sans-serif");
title.css("color", "navy")
var body = $("body");
body.prepend(title);
title.fadeIn(5000);
title.fadeOut(5000);
          

var title = $("<h1>¡Hola!</h1>")
            .css("font-family", "sans-serif")
            .css("color", "navy");
$("body").prepend(title);
title.fadeIn(5000)
     .fadeOut(5000);
          

Lectura y escritura de atributos


// Lee el atributo href del primer enlace:
$("a").first().attr("href");

// Escribe el atributo title de todos los nombres de escritor
$(".escritor").attr("title", "Esto es un nombre de escritor");

// Cambia varios atributos a la vez
$("#foto-cervantes").attr({src: "cervantes-2.jpg",
                            alt: "Cervantes por Luis de Madrazo"});

// Elimina un atributo
$("#foto-quevedo").removeAttr("height");
          

Página de demostración

Lectura y escritura de propiedades CSS


// Lee el valor de una propiedad CSS:
$(".info").first().css("font-size");

// Establece el valor de una propiedad CSS:
$(".info").css("font-variant", "small-caps");

// Establece una propiedad compuesta
$(".retrato").css("border", "solid red 2px");

// Establece varias propiedades a la vez:
$(".retrato").css({"padding": "5px",
                    "background-color": "gray",
                    "filter": "grayscale(50%)"});
          

Lectura y escritura del atributo class


// Elimina la pertenencia a una clase:
$(".escritor").last().removeClass("escritor");

// Añade la pertenencia a una clase:
$("a").last().addClass("encuadrado");

// Comprueba la pertenencia a una clase:
$("a").last().is(".encuadrado");

// Alterna la pertenencia a una clase:
$("a").last().toggleClass("encuadrado");
          

Lectura y escritura del contenido de un elemento


// Lee el contenido de un elemento como texto sin formato:
var t1 = $(".info").first().text();

// Lee el contenido de un elemento como texto HTML:
var t2 = $(".info").first().html();

// Establece el contenido de un elemento (texto plano):
$(".info").first().text("Texto borrado.");

// Establece el contenido de un elemento (HTML):
$(".info").first().html("Texto <strong>borrado</strong>.");
          

El modelo DOM


<!DOCTYPE html>
<html>
  <head>
    <title>Barney says...</title>
  </head>
  <body>
    <h1>Barney says</h1>
    <p>
      This is going to be <em>legendary</em>
    </p>
  </body>
</html>
          

El modelo DOM

Representación del modelo DOM

Añadir contenido


// Añade un nuevo hijo (es decir, inserta como último hijo)
$("ul").append("<li><div class='escritor'>José de Espronceda</div></li>");

// Añade un nuevo hijo (es decir, inserta como primer hijo)
let alfonso_div = $('<li>').append($('<div>')
                                    .addClass("escritor")
                                    .text("Alfonso X el Sabio"));
$("ul").prepend(alfonso_div);

// Añade dos elementos hermanos, uno inmediatamente antes
// y el otro inmediatamente después de cada elemento h1:
$("h1").before("<hr>");
$("h1").after("<hr>");
          
El elemento hr representa una línea horizontal.

Añadir contenido


// Se pueden hacer las inserciones a la inversa,
// invocando los métodos sobre el nodo a insertar:
$(document.createTextNode(": escritores")).appendTo("h1");
$("<cite>[Wikipedia] </cite>").prependTo($(".info"));

$("<hr>").insertBefore("ul");
$("<hr>").insertAfter("ul");
          
Contenido a ser insertado.
Selector para los elementos a los cuales se añadirá el contenido.

Añadir contenido


// Envuelve elementos en otro elemento:
$(".retrato").wrap("<div>");

// Envuelve el contenido de un elemento dentro de otro:
$(".escritor").wrapInner("<strong>");
          
Todos los elementos coincidentes con el selector (es decir, todos los elementos de clase retrato) son envueltos dentro de un nuevo elemento div. El viejo padre de cada uno de esos elementos se convierte ahora en el padre del nuevo elemento div.
El contenido de cada elemento coincidente con el selector (es decir, todos los elementos de clase escritor) es envuelto dentro de un nuevo elemento strong. El nuevo elemento strong se convierte ahora en el único hijo de cada uno de esos elementos.

Clonar contenido


$(".retrato").clone().insertBefore("ul");
          
Se crea una copia de todos los elementos seleccionados por el selector (es decir, todos los elementos de clase retrato).
Las copias se insertan antes de cada elemento ul de la página.

Eliminar contenido


// Vacía el contenido de un nodo, pero no elimina el nodo:
$(".retratos").first().empty();

// Elimina un nodo con todo su contenido:
$("li").last().remove();

// Desenlaza un nodo del árbol, pero se conserva en una variable
let node = $("h1").detach();
$("body").append(node);
          
Se eliminan del árbol DOM todos los elementos h1, pero se mantienen en memoria y se puede acceder a ellos a través de la variable node.
Se añaden los elementos eliminados a una nueva posición del árbol, como últimos hijos del elemento body.

Acceso a formularios


// Lee el valor de un control:
$("input[name='pregunta1'").val();

// Cambia el valor de un control:
$("input[name='pregunta2'").val("Córdoba");

// Lee el botón tipo radio marcado:
$("input[name='pregunta3']:checked").val();

// Marca un botón de tipo radio:
$("input[name='pregunta3'][value='quevedo']").prop("checked", true);
          
El selector selecciona el botón de tipo radio con nombre pregunta3 y valor quevedo. Recuerda que todos los botones de tipo radio de un mismo grupo tienen el mismo nombre pero valores distintos. Sólo un botón de tipo radio de un mismo grupo puede estar marcado a la vez.

Acceso a formularios


// Lee los controles marcados de tipo checkbox:
$("input[name='pregunta4']:checked").each(function(i, e) {
    console.log($(e).attr("value"));
});

// Marca controles de tipo checkbox:
$("input[name='pregunta4']").val(['gongora', 'cervantes']);
          
El selector selecciona los botones de tipo checkbox con nombre pregunta4. Recuierda que todos los botones de tipo checkbox de un mismo grupo tienen el mismo nombre pero valores distintos. Varios botones de tipo checkbox pueden estar marcados a la vez.
El método each itera sobre todos los elementos seleccionados por el selector, ejecutando la función proporcionada para cada uno de ellos.
La función recibe dos parámetros: i es el índice del elemento actual en la iteración, y e es el elemento del árbol DOM sobre el cual se está iterando.
El elemento del árbol DOM e se envuelve en un objeto JQuery para poder usar métodos de JQuery como attr en él.
El método val se puede usar para marcar varios botones de tipo checkbox a la vez pasando un array con los valores de aquellos que se desee marcar.

Manejadores de eventos

Permiten registrar acciones a llevar a cabo cuando ocurran determinados eventos sobre un elemento de la página. Por ejemplo:

  • Se hace click sobre el elemento.
  • El cursor pasa por encima del elemento.
  • Cambia el valor de un control de formulario.

Eventos de carga del documento


$(document).ready(function() {
  // Código a ejecutar cuando se haya cargado
  // el árbol DOM del documento.
});

$(window).on("load", function() {
  // Código a ejecutar cuando se haya representado la página
  // y cargado todos sus recursos adicionales.
});

$(window).on("unload", function() {
  // Código a ejecutar cuando se abandone la página
  // (se sigue un hipervínculo, se recarga el documento,
  // se va hacia atrás o adelante).
});
          

Eventos del navegador


$("#img1").on("error", function() {
  // Código a ejecutar cuando se produzca un error
  // en la carga del elemento (p.e. una imagen).
});

$(window).resize(function() {
  // Código a ejecutar cuando se cambie el tamaño
  // de la ventana.
});

$(window).scroll(function() {
  // Código a ejecutar cuando se haga scroll en la página.
});

$("#e1").scroll(function() {
  // Código a ejecutar cuando se haga scroll
  // en el elemento con identificador #e1.
});
          
Se ejecuta el manejador de eventos cuando se produzca un error en la carga del elemento con identificador img1 (por ejemplo, porque la URL sea incorrecta, haya un fallo temporal de red o del servidor, etc.).
Se ejecuta el manejador de eventos cuando se haga scroll en el contenido del elemento con identificador e1. El elemento debe disponer de su propia barra de desplazamiento (por ejemplo, porque su propiedad CSS overflow esté establecida a auto o scroll).

Eventos en formularios


$("input[name=email]").on("change", function() {
  // Código a ejecutar cuando cambie el valor del control.
});

$("form").on("submit", function(event) {
  // Código a ejecutar cuando el usuario presione en un botón
  // de envío del formulario.
  // En este ejemplo, se está evitando el envío:
  event.preventDefault();
});
          
Se ejecuta el manejador de eventos cuando cambie el valor del control con nombre email (por ejemplo, cuando el usuario escriba algo y luego el control pierda el foco).
El método preventDefault del objeto evento evita la acción predeterminada asociada al mismo (en este caso, enviar el formulario al servidor).

Eventos en formularios (foco)


$("input[name=email]").on("focus", function() {
  // Código a ejecutar cuando el control consiga el foco.
});

$("input[name=email]").on("blur", function() {
  // Código a ejecutar cuando el control pierda el foco.
});

$("#e1").on("focusin", function() {
  // Código a ejecutar cuando el elemento #e1
  // o algún descendiente suyo consiga el foco.
});

$("#e1").on("focusout", function() {
  // Código a ejecutar cuando el elemento #e1
  // o algún descendiente suyo pierda el foco.
});
          

Eventos del cursor


$("#e1").on("click", function() {
  // Código a ejecutar cuando el usuario haga click
  // sobre el elemento #e1.
});

$("#e1").on("dblclick", function() {
  // Código a ejecutar cuando el usuario haga doble click
  // sobre el elemento #e1.
});
          

Eventos del cursor


$("#e1").on("mouseenter", function() {
  // Código a ejecutar cuando el puntero entre en el área
  // del elemento #e1.
});

$("#e1").on("mouseleave", function() {
  // Código a ejecutar cuando el puntero abandone el área
  // del elemento #e1.
});
          

Eventos del cursor


$("#e1").on("mousedown", function(event) {
  // Se ejecuta cuando se presiona un botón del ratón
  // mientras el puntero está dentro del área de visualización de #e1.
  // También se puede comprobar qué botón está pulsado.
  switch(event.button) {
    case 0:
      // botón izquierdo presionado
      break;
    case 1:
      // botón central presionado
      break;
    case 2:
      // botón derecho presionado
      break;
  }
});
          
El objeto evento pasado al manejador contiene información acerca del el evento (por ejemplo, qué botón del ratón se pulsó).

Eventos del cursor


$("#e1").on("mouseup", function(event) {
  // Código a ejecutar cuando se suelte un botón
  // dentro del área del elemento #e1.
  // Se puede saber qué botón se ha liberado con event.button.
});

$("#e1").on("mousemove", function(event) {
  // Código a ejecutar cuando se mueva el cursor
  // dentro del área del elemento #e1.
});
          

En todos los eventos anteriores se pueden obtener las coordenadas del cursor con event.pageX, event.pageY, event.screenX, event.screenY, event.offsetX y event.offsetY. También se puede saber qué botones del ratón están presionados con event.buttons. Más información sobre eventos de ratón.

Referencias

Referencias