- 1. Introducción
En este apartado profundizamos en el trabajo con objetos.
- Es aconsejable inicializar los objetos cuando se crean.
- El constructor hace esta tarea, pero en Javascript es preferible hacerlo sin usar el constructor.
// formas permitidas, pero no recomendadas, excepto para Date()
let a = new Number(); // objeto de clase Number. A evitar. Debe usarse el tipo primitivo.
let b = new Boolean(); // objeto de clase Boolean. A evitar. Debe usarse el tipo primitivo.
let c = new String(); // objeto de clase String. A evitar. Debe usarse el tipo primitivo.
let d = new Array(); // objeto de clase Array. A evitar. Debe usarse el tipo primitivo.
let e = new Date(); // objeto de clase Date.
let f = new RegExp(); // objeto de clase RegExp. A evitar.
let g = new Function(); // getElementbyclass objeto de clase Function. A evitar.
let h = new Object(); // objeto de clase Object genérico. A evitar.// formas recomendadas
let a = 0; // número primitivo
let b = false; // booleano primitivo
let c = ""; // texto primitivo
let d = []; // objeto array
let f = /()/; // objeto regexp
let g = function(){}; // objeto function
let h = {}; // objeto objectPara trabajar con fechas debemos crear un objeto de la clase Date.
Una forma de llamar al constructor es:
let fecha = new Date(año, mes, día, hora, minutos, segundos, milisegundos)IMPORTANTE: Los meses se numeran empezando en 0. Enero es el mes 0, Febrero el 1, ...
// Ejemplos
let f1 = new Date(2017, 00, 01, 22, 30, 00, 999); // 1 Enero de 2017, 22:30:00.999
let f2 = new Date(2017, 00, 01, 22, 30, 00); // 1 Enero de 2017, 22:30:00
let f3 = new Date(2017, 00, 01, 22, 30); // 1 Enero de 2017, 22:30:00
let f4 = new Date(2017, 00, 01); // 1 Enero de 2017, 00:00:00
let f5 = new Date(); // Fecha y hora actualOtra forma de llamar al constructor es:
let fecha = new Date("YYYY-MM-DDTHH:MI:SSZ");NOTAS:
- En este caso Enero sí empieza en 1.
- La fecha y la hora se separan con una
Tmayúscula.- La hora UTC (Universal Time Coordinated) o GMT (Greenwich Mean Time) se define con una letra mayúscula
Z.- Si se crea una fecha/hora en GMT, la fecha y la hora se convertirán a la hora local del usuario.
- Para indicar otra zona horaria deberemos sustituir la letra Z por +HH:MI o -HH:MI
// Ejemplos
let f1 = new Date("2017-01-01T23:30:00"); // Hora local, tal cual
let f2 = new Date("2017-01-01T23:30:00+01:00"); // Hora de España
let f3 = new Date("2017-01-01T23:30:00-05:00"); // Hora de Nueva York
let f4 = new Date("2017-01-01T23:30:00Z"); // Hora de Londres y Canarias, a nosotros nos aparecerá una hora más Conversión de Date a String
Suele ser habitual la conversión del tipo date al tipo string. Para ello podemos usar el método toISOString
let f1 = new Date() // type object date
let s1 = f1.toISOString() // type stringExtracción de fecha
Para obtener sólo la fecha, sin la hora, podemos hacer:
let f1 = new Date() // type object date
let s1 = f1.toISOString() // type string
let fecha = s1.split('T')[0] // type string Extracción de hora
Para obtener sólo la hora, sin la fecha, podemos hacer:
let f1 = new Date() // type object date
let s1 = f1.toISOString() // type string
// Todas la variables que aparecen a continuación son de tipo string
let hora = s1.split('T')[1]
let horaSinZ = s1.split('T')[1].split('Z')[0]
let horaSinMS = s1.split('T')[1].split('.')[0]Las expresiones regulares es un asunto de cierta complejidad. En las referencias tienes un desarrollo detallado. Una expresión regular no es más que un patrón de texto.
Las expresiones regulares tienen multiples utilidades. Una de las más frecuentes es la validación de datos respecto a un patrón determinado.
Los siguientes carácteres tienen un significado especial:
^ Indica el principio de una cadena
$ Indica el final de una cadena
() Un agrupamiento de parte de una expresión
[] Un conjunto de caracteres de la expresión
{} Indica un número o intervalo de longitud de la expresión
. Cualquier caracter salvo el salto de línea
? 0-1 ocurrencias de la expresión
+ 1-n ocurrencias de la expresión
* 0-n ocurrencias de la expresión
\ Para escribir un caracter especial como los anteriores y que sea tratado como un literal
| Para indicar una disyunción lógica (para elegir entre dos valores: a|b se tiene que cumplir al menos uno de los dos)
Ejemplo de validación de teléfono:
let telefono = /^[6789][0-9]{8}$/;
telefono.test ('123456789'); // false
telefono.test ( '95566622'); // false
telefono.test ('95566622a'); // false
telefono.test ('609123456'); // trueEjemplo de validación de código postal:
let codigoPostal = /^[0-9]{4,5}$/;
codigoPostal.test ( '14500'); // true
codigoPostal.test ( '9500'); // true
codigoPostal.test ('A11450'); // false
codigoPostal.test ( '1'); // falseEjemplo de validación de URLs:
let url = /^(http|ftp|https)\:\/\/[a-z0-9\_-]+(\.[a-z0-9\_-]+)*$/
url.test ('https://google.es'); // true
url.test ('ftp://ftp.rediris.es'); // true
url.test ('file:///bin/bash'); // false
url.test ('https://google.es/index.html'); // falseEjemplo de validación de e-mail:
let email = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
email.test ('jamj2000@gmail.com'); // true
email.test ('pepe_lopez@ventas.tienda.com'); // true
email.test ('pepe#lopez@tienda.com'); // false
email.test ('pepe_lopez@ventas/tienda.com'); // falseEjemplo dentro de página web
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Validación de Código Postal</title>
</head>
<body>
<input id="cod" type="text" placeholder="Código Postal">
<input id="val" type="button" value="Validar">
<script>
function validarCP(){
return /^[0-9]{4,5}$/.test (document.getElementById('cod').value);
}
document.getElementById('val').addEventListener('click', function () {
if (validarCP()) alert('Código Postal CORRECTO')
else alert('Código Postal NO VÁLIDO');
});
</script>
</body>
</html>REFERENCIAS:
Se representa con { }, permite desempacar propiedades de objetos en distintas variables.
Se utiliza en numerosos ámbitos, para mayor información consultar el siguiente enlace:
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Ejemplo 1: Asignación de valores a variables desde un objeto origen
const user = {
id: 42,
is_verified: true
};
const {id, is_verified} = user;
console.log(id); // 42
console.log(is_verified); // trueEjemplo 2: Desempacar campos de objetos pasados como parámetro de función
const usuario = {
id: 42,
nombre: 'jose',
};
function usuarioId({id}) {
return id;
}
console.log(usuarioId(usuario)); // 42También llamado spread operator y representado por 3 puntos ..., permite expandir (sacar del objeto) las propiedades.
Se utiliza en numerosos ámbitos, para mayor información consultar el siguiente enlace:
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Spread_syntax
Ejemplo 1: Copia superficial de un objeto
let obj1 = { nombre: 'jose', edad: 42 };
let objClonado = { ...obj1 };
console.log(objClonado); // { nombre: "jose", edad: 42 }Ejemplo 2: Concatenación de propiedades
let obj1 = { nombre: 'jose', edad: 42 };
let obj2 = { nombre: 'juan', peso: 73 };
let obj3 = { ...obj1, ...obj2 };
console.log(obj3) // { nombre: "juan", edad: 42, peso: 73 }Tenemos el siguiente objeto del que deseamos realizar una copia:
let persona = { nombre:"José", edad:30, direccion: {calle: "antigua", num: 1} };NOTA: el código
let copia = persona, no hace una copia.Simplemente crea una referencia o "alias" llamado
copiaque apunta al mismo sitio quepersona. Cualquier cambio en el objeto se ve reflejado en ambas variables.let copia = persona; persona.peso = 100; // copia = {nombre: "José", edad: 30, peso: 100} ``
let persona = { nombre:"José", edad:30, direccion: {calle: "antigua", num: 1} };
let copia_superficial = {};
// shallow copy (copia superficial)
Object.assign(copia_superficial, persona);
copia_superficial.nombre = "Juan";
persona.nombre; // "José";
// No se copian los valores de los objetos internos. Sólo se copia su referencia. Por tanto:
copia_superficial.direccion.calle = "nueva";
persona.direccion.calle; // "nueva" Existe una forma más moderna de realizar la copia superficial, y es usando el operador de expansion:
let persona = { nombre:"José", edad:30, direccion: {calle: "antigua", num: 1} };
let copia_superficial = { ...persona }; // shallow copy (copia superficial)
copia_superficial.nombre = "Juan";
persona.nombre; // "José";
// No se copian los valores de los objetos internos. Sólo se copia su referencia. Por tanto:
copia_superficial.direccion.calle = "nueva";
persona.direccion.calle; // "nueva" Para un clonado profundo, necesitamos usar otra alternativa ya que Object.assign() copia valores de propiedades. Si el valor en la fuente es una referencia a un objeto, solo se copia la referencia en sí, como valor de la propiedad.
let persona = { nombre:"José", edad:30, direccion: {calle: "antigua", num: 1} };
// deep copy (copia profunda)
let copia_profunda = JSON.parse(JSON.stringify(persona));
// Se copian los valores de los objetos internos. Por tanto:
copia_profunda.direccion.calle = "ancha";
persona.direccion.calle; // "antigua"; RESUMEN:
JSON.stringify()convierte unObjeto JavascriptaStringJSON.parse()convierte unStringaObjeto Javascript.
NOTA:
JSON es un formato de intercambio de datos que está estándarizado y que tiene las siguientes características:
- Tanto las claves como los valores deben estar entre comillas dobles, no se permiten comillas simples.
- Los valores de tipo number y de tipo boolean no llevan comillas
- No se permite el uso de trailing commas (comas finales)
- No se permite el uso de comentarios
Estas características a menudo son percibidas como limitaciones. Por ello existen formatos derivados de JSON con menores restricciones. Por ejemplo, VSCode usa archivos de configuración con extensión
.json, pero el formato real es JSONC (JSON con Comentarios), que permite comentarios y comas finales.Otro formato derivado de JSON es JSON5
Ni JSONC ni JSON5 están estándarizados.
Aprovechamos la ocasión de haber visto previamente las funciones JSON.stringify() y JSON.parse() para hablar de la serialización.
¿QUÉ SE ENTIENDE POR SERIALIAR?
Simplificando mucho, podemos decir que serializar es pasar unos datos "paralelos" o compuestos a datos "serie" o simples. Por ejemplo, pasar un objeto a un string. Un string se considera un dato serie puesto que está compuesto por una serie de caracteres uno tras otro.
CÓMO Y CUÁNDO SERIALIZAR
const string = await JSON.stringfy(objeto)La serialización es necesaria en los siguientes escenarios:
- Al enviar información por la red
- Al guardar información en un archivo
CÓMO Y CUÁNDO DESERIALIZAR
const objeto = await JSON.parse(string)La deserialización es necesaria en los siguientes escenarios:
- Al recibir información de la red
- Al leer información en un archivo
Existe una forma más moderna de realizar la copia profunda, y es usando la función structuredClone:
let persona = { nombre:"José", edad:30, direccion: {calle: "antigua", num: 1} };
// deep copy (copia profunda)
let copia_profunda = structuredClone(persona);
// Se copian los valores de los objetos internos. Por tanto:
copia_profunda.direccion.calle = "ancha";
persona.direccion.calle; // "antigua"; Los objetos tienen propiedades y métodos.
let persona = {
nombre: "José", // Propiedad
edad: 30, // Propiedad
altura: 1.70, // Propiedad
peso: 100, // Propiedad
imc: function() { return this.peso / (this.altura*this.altura) } // Método
}
// Tanto propiedades como métodos pueden añadirse después de haberse definido el objeto
// Otro método
persona.saluda = function (saludo) {
console.log (saludo + ', me llamo ' + this.nombre);
}
persona.imc(); // 34.60
persona.saluda('Buenos días'); // Buenos días, me llamo JoséEl lenguaje Javascript es un lenguaje basado en prototipos, donde no hay clases explícitas y los objetos heredan directamente de otros objetos. Ésta es su forma de implementar la Programación Orientada a Objetos.
En los lenguajes basados en clases, normalmente se crea una clase en tiempo de compilación y luego se instancian las instancias de la clase, ya sea en tiempo de compilación o en tiempo de ejecución. No puede cambiar el número o el tipo de propiedades de una clase después de definir la clase. Sin embargo, en JavaScript, puede agregar o eliminar propiedades de cualquier objeto en tiempo de ejecución. Si agrega una propiedad a un objeto que se utiliza como prototipo para un conjunto de objetos, los objetos para los que es el prototipo también obtienen la nueva propiedad.
// Función constructura del prototipo
function Persona (nombre, altura, peso) {
this.nombre = nombre;
this.altura = altura;
this.peso = peso;
this.imc = function () { return this.peso / (this.altura*this.altura) };
}
let pepe = new Persona ('José', 1.70, 100);
let juan = new Persona ('Juan', 1.60, 90);
pepe.imc();
// Añadimos una propiedad al prototipo
Persona.prototype.mortal = true;
// Añadimos un método al prototipo
Persona.prototype.saluda = function (saludo) {
console.log (saludo + ', me llamo ' + this.nombre);
}
juan.saluda ('Hola');
pepe.saluda ('Buenos días');Sólo disponible a partir de ES6. Es azúcar sintáctico, puesto que en el fondo Javascript sigue siendo un lenguaje basado en prototipos.
class Persona {
constructor (nombre, altura, peso) {
this.nombre = nombre;
this.altura = altura;
this.peso = peso;
this.mortal = true;
}
// No hay coma de separación
imc () { // Método. Observa que no hay palabra function
return this.peso / (this.altura*this.altura);
}
// No hay coma de separación
saluda (saludo) { // Método. Observa que no hay palabra function
console.log (saludo + ', me llamo ' + this.nombre);
}
} // Fin de clase
let pepe = new Persona ('José', 1.70, 100);REFERENCIAS:
Cuando trabajamos con el navegador web, el principal objeto es window, el cual posee innumerables propiedades y métodos.
Tres métodos interesantes son los que nos proporcionan cajas de diálogo:
- alert
- confirm
- prompt
window.alert ('Mensaje de bienvenida');
window.confirm ('¿De verdad deseas hacer eso?');
window.prompt ('Escribe tu nombre y apellidos: ');La cajas de diálogo confirm y prompt devuelven un valor. Por tanto, suele recogerse dicho valor y evaluarlo o tratarlo de alguna forma. Ejemplos:
if ( window.confirm ('¿De verdad deseas hacer eso?') )
window.console.log ('Bien, tú lo has querido');
window.console.log ('Has dicho que te llamas ', window.prompt ('Escribe tu nombre y apellidos: '));Tres propiedades interesantes (que a su vez son objetos) son:
- navigator
- document
- console
Estos objetos los vemos en los siguientes apartados. Tiene a su vez sus propias propiedades y métodos. Ejemplo de propiedades para estos objetos son:
window.navigator.appVersion
window.document.titleNOTA: Todos estas propiedades y métodos pueden escribirse sin el prefijo window.
Por ejemplo, suele escribirse
alert ('Hola')en lugar dewindow.alert ('Hola')y
documenten lugar dewindow.document
Nos permite acceder a las propiedades y métodos del navegador web.
navigator.geolocation
.getCurrentPosition( position => {
console.log ( position.coords.latitude + ', ' + position.coords.longitude )
});// Igual al anterior, guardado en una función y comprobando previamente el soporte del navegador
// Definición de función
function getLocation() {
if ("geolocation" in navigator) // if (navigator.geolocation)
return navigator.geolocation
.getCurrentPosition( position => {
console.log ( position.coords.latitude + ', ' + position.coords.longitude )
});
else
return "Geolocation is not supported by this browser.";
}
// Llamada a la función
getLocation();A través de este objeto accedemos al DOM (Document Object Model), el cual es un modelo del documento actual. De esta manera podemos acceder a cualquier elemento del documento y modificar su contenido.
Métodos interesantes son:
- createElement
- remove
- appendChild
- getElementById
- getElementsByClassName
- querySelector
- getAttribute
- setAttribute
Propiedades interesantes son:
- textContent
- innerHTML
- value ( utilizado para inputs )
Ejemplo
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>DOM</title>
</head>
<body>
<ul id="lista"> </ul>
<input id="boton" type="button" value="Pulsame">
<script>
let list = document.getElementById('lista');
document.getElementById('boton').addEventListener ('click', function(){
for (let i = 1; i <= 5; i++) {
let item = document.createElement('li');
item.appendChild(document.createTextNode('Item ' + i));
item.onclick = function(ev) {
console.log('Item ' + i + ' ha sido pulsado.');
};
list.appendChild(item);
}
});
</script>
</body>
</html>Se utiliza para mostrar mensajes por consola.
let agenda = [
{ nombre: 'José', telefono: 300300300 },
{ nombre: 'Eva', telefono: 200200200 },
{ nombre: 'Ana', telefono: 100100100 },
{ nombre: 'Juana', telefono: 111222333 }
];
console.clear (); // Limpia la consola
console.log ('Mensaje de log'); // Muestra mensaje de log
console.info ('Mensaje de información'); // Muestra mensaje de información
console.warn ('Mensaje de aviso'); // Muestra mensaje de aviso
console.error ('Mensaje de error'); // Muestra mensaje de error
console.debug ('Mensaje de depuración'); // Muestra mensaje de depuración
console.table (agenda); // Muestra en forma de tabla. Para navegador y nodejs
console.time ('id') // Inicia temporizador
console.timeEnd('id') // Muestra tiempo transcurrido desde console.time('id')NOTA: En NodeJS, el objeto console existe por si mismo, es decir, en NodeJS no podemos escribir window.console.