JavaScript
Índice
- 1.Introducción
- 2.Ecmascript
- 2.1.Historia de la ECMAScript
- 2.2.ECMAScript 6
- 2.2.1.Variables let y const
- 2.2.2.Funciones flecha (arrow)
- 2.2.3.Clases
- 2.2.4.Variable this
- 2.2.5.Template strings
- 2.2.6.Desestructuración (destructuring)
- 2.2.7.Valores por defecto
- 2.2.8.Módulos
- 2.3.Transpiladores
- 3.jQuery
- 3.1.Obtener jQuery
- 3.2.Cómo funciona jQuery: El Objeto $
- 3.3.Interactuando con el DOM
- 3.4.Selectores, filtros y CSS
- 3.5.Manipulando el DOM
- 3.5.1.Propiedades CSS
- 3.5.2.Atributos de los nodos
- 3.5.3.Añadir contenido al DOM
- 3.5.4.Borrar nodos
- 3.6.Funciones generales
- 3.7.Sistema de eventos (events)
- 3.7.1.Tabla de eventos
- 3.8.Formularios
- 3.9.AJAX
- 3.10.Componentes (widgets)
- 3.11.Patrones de uso
- 4.Frameworks JavaScript
- 4.1.Angular
- 4.2.VueJS
- 4.3.React
- 4.4.Vanilla JavaScript
- 5.Typescript
- 5.1.Superset
- 5.2.Instalación
- 5.3.Crear y compilar un archivo ts
- 5.4.Playground
- Bibliografía
1.Introducción
2.Ecmascript
2.1.Historia de la ECMAScript
2.2.ECMAScript 6
2.2.1.Variables let y const
var variable = "valor";
// ES5 function () { var variable; console.log(variable); if (true) { variable = "Hola mundo"; } console.log(variable); };
Hola mundo
// ES6 function () { console.log(variable); if (true) { let variable = "Hola mundo"; } console.log(variable); };
undefined
const IVA = 21; console.log(IVA); IVA = 25; console.log(IVA);
const IVA; IVA = 21; console.log(IVA);
const PERSONA = { id: "01", nombre: "Jana" } PERSONA.nombre = "Gina"; console.log(PERSONA.nombre);
2.2.2.Funciones flecha (arrow)
let nuevaFuncion = () => { //código de la función }
nuevaFuncion();
let saludar = (nombre, tratamiento) => { alert('Hola ' + tratamiento + ' ' + nombre) } //invocación saludar('Jana', 'srta.');
let cuadrado = numero => { return numero * numero; }
let cuadrado = numero => numero * numero;
// ES5 var cuadrado = function(numero) { return numero * numero; }
let getBienvenida = () => "Hola mundo";
var getBienvenida = function () { return "Hola mundo"; };
2.2.3.Clases
class Persona { constructor(nombre) { this.nombre = nombre; } } var p1 = new Persona("Carles"); console.log(p1.nombre);
class Persona { constructor(nombre,apellidos) { this._nombre = nombre; this._apellidos = apellidos; } get nombre(){ return this._nombre; } set nombre(nombre){ this._nombre = nombre; } get apellidos(){ return this._apellidos; } set apellidos(apellidos){ this._apellidos = apellidos; } } var p1 = new Persona("Carles","Santamaria"); console.log(p1.nombre); console.log(p1.apellidos);
class Punto { constructor(x, y) { this.x = x; this.y = y; } static distancia(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.sqrt(dx*dx + dy*dy); } } const p1 = new Punto(5, 5); const p2 = new Punto(10, 10); console.log(Punto.distancia(p1, p2));
2.2.4.Variable this
// ES5 function Persona() { this.edad = 18; var that = this; setTimeout(function() { console.log(that.edad); }, 5000) } var p = new Persona();
// ES6 function Persona() { this.edad = 18; setTimeout(() => { console.log(this.edad); }, 5000) } var p = new Persona();
2.2.5.Template strings
var nombre = "Josep Maria"; var saludar = "Estimado/da" + nombre;
var nombre = "Josep Maria"; var apellidos = "Puig" var profesion = "profesor"; var localidad = "Barcelona"; var descripcion = "<strong>" + nombre + "" + apellidos + "</strong>es" + profesion + " a " + localidad;
var nombre = "Josep Maria"; var apellidos = "Puig" var profesion = "profesor"; var localidad = "Barcelona"; var descripcion = `<strong>${nombre} ${apellidos}</strong> es ${profesion} a ${localidad}`;
//ES5 console.log("línea 1 de la cadena de texto\n\ línea 2 de la cadena de texto");
//ES6 console.log(`línea 1 de la cadena de texto línea 2 de la cadena de texto`);
2.2.6.Desestructuración (destructuring)
const persona = { nombre: "Eduard", apellidos: "Punset", twitter: "epunset", web: "eduardpunset.es", }; const nombre = persona.nombre; const apellidos = persona.apellidos;
const { nombre, apellidos } = persona;
const eduard = { nombre: "Eduard", apellidos: "Punset", links: { social: { twitter: 'https://twitter.com/epunset', facebook: 'https://facebook.com/eduardpunset', }, web: { blog: 'http://www.eduardpunset.es' } } };
const twitter = eduard.links.social.twitter; const facebook = eduard.links.social.facebook;
const { twitter, facebook } = eduard.links.social; console.log(twitter, facebook);
2.2.7.Valores por defecto
//ES5 function(valor) { valor = valor || "hola"; } //ES6 function(valor = "hola") {...};
2.2.8.Módulos
// archivo lib/persona.js modulo "persona" { export function hola(nombre) { return nombre; } }
// archivo: app.js importe { hello } from "persona"; var app = { foo: function() { hola("Jana"); } } export app;
2.3.Transpiladores
3.jQuery
3.1.Obtener jQuery
$ npm install jquery
<script src="jquery.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script>
3.2.Cómo funciona jQuery: El Objeto $
var jQuery = window.jQuery = window.$
3.3.Interactuando con el DOM
<html> <head> <title>Ejercicio jQuery</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script> </head> <body> <p id="p1">¡Hola Mundo!</p> < script> $(function(){ // 1 var resultado = $('#p1').texto(); // 2 alert(resultado) }); </script> </body> </html>
3.4.Selectores, filtros y CSS
$('*') |
Todos los elementos |
$('#nombre’) |
Elemento con id=nombre |
$('.clase') |
Elementos que tengan la .clase CSS |
$('img') |
Elementos |
$('img, p, selectorN') |
Combina los elementos img, p, selectorN |
$('a[rel="nofollow"]') |
Todos los a con el atributo rel="nofollow" |
$('[atributo|="valor"]') |
Atributo sea o empiece por valor |
$('[attribute~="value"]') |
Atributo que contenga valor delimitado por espacios. |
$('[atributo!="valor"]') |
Que el atributo no tenga el siguiente valor |
$('[atributo^="valor"]') |
Que el valor del atributo empiece por valor |
$('[atributo$="valor"]') |
Que el valor del atributo acabe con valor |
$('[atributo]') |
Que el elemento contenga el atributo |
$('[atributo1="1"][atributo2="2]') |
Que contengan todos los atributos con valores |
$('tr:first-child') |
La primera fila de una tabla. También podemos emplear :last-child, y :nth-child(4n) |
$("tr:even") |
Fila impar. También se puede llamar a las pares con odd |
$('tr:eq(3)') |
El tercer elemento del conjunto seleccionado. En este caso, la tercera fila del conjunto de todas las tablas de la página. También podemos emplear
|
$('tr:first') |
El primer elemento. También podemos con el último con :last |
$("div:contains('Libro')") |
Seleccionará los elementos div que en su contenido aparezca la palabra Libro |
$("div:has(p)") |
Elementos div que contenga otro elemento p |
$("td:pariente") |
Elementos que son padres de otro nodo, incluido nodos de texto |
$('img').each(function(index, elemento) { console.log( elemento.src ) });
$('img').length; // devolverá el total de imágenes que contiene el documento.
<div><p>Content</p></div> <div id="p1"> <p>Content 2</p> < /div> $('p', $('#p1'));
3.5.Manipulando el DOM
3.5.1.Propiedades CSS
$('p').css('color', 'red');
$('p').css({ 'color': 'grey', 'padding': '5px', 'background-color': 'yellow' });
$('p').css('color')
.show() |
Nos mostrará el elemento si estaba escondido |
.hide() |
Esconde un elemento |
.toggle() |
Actúa a modo de interruptor. Si el elemento está escondido, lo muestra y si el elemento es visible, lo esconde |
$('#id').addClass('nombredelaclase')
$('#id').hasClass('nombredelaclase')
$('#id').removeClass('nombredelaclase')
3.5.2.Atributos de los nodos
<img width="34" /> $('img').attr('width', '44')
3.5.3.Añadir contenido al DOM
<p id="uno">Una prueba</p> $('.inner').wrap('<div class="new" />'); <div class="new"> <p id="uno">Una prueba</p> < /div>
.append('contento') |
Añade el contenido al final del selector |
.prepend() |
Añade el contenido al principio del selector |
.html() |
Recupera el contenido de un selector o se lo asigna. Siempre contenido html |
.texto() |
Recupera el texto de un selector, sin etiquetas. También lo asigna |
3.5.4.Borrar nodos
3.6.Funciones generales
a = [1,2,3,4,5] resultado = 0 $.each(a, function(index, valor) { resultado += a } alert('el resultado es' + a)
$('.item').each(function(ind) { $(ind).text() })
$('.item').each(function(ind) { $(ind).text() })
a = {uno: 'hola', dos:'dos' } b = {uno:'si', tres:'quepasa'} $.extend(a, b) a == {uno:'si', tres:'quepasa', dos:'dos'}
var a = { 'hola': function() { return 1; }, 'adios': function() { return 2; } } var mixin = { 'hola': function() { return 2; } } $.extend(a, mixin) console.info( a.hola() == 2 ) console.info( a.adios() == 2 )
$.extend(a.prototype, mixin)
3.7.Sistema de eventos (events)
$('a').on('click', function() { contador += 1 })
$('#idselect').on('change', manipulador)
$('a').on({ 'mousenter': function(evt) { $(this).css('color', 'black') }, 'click': function(evt) { $(this).toggle(); } });
<script> $(function(){ $('tr').click(function(){ alert('clic a tr');}) .height(30) .css( 'background-color', '#eaeaea'); $('a').click(function(e){ alert('clic a a'); e.stopPropagation() }); }); </script> </head> <body> <table> <tr> <td><a>Hola</a></td> </tr> </table>
$('tr').off('click');
$('tr').trigger('click');
var segundos = 0 setInterval(function(){ $('#p1').text( ++segundos ) .trigger('segundo', [segundos]) }, 1000) $('#p1').on('segundo', function(event, data){ if(data==10) segundos = 0 })
3.7.1.Tabla de eventos
blur |
Cuando en un campo de formulario perdemos el foco del teclado |
focus |
Cuando un elemento de un formulario recibe un clic del ratón |
resize |
La ventana cambia de tamaño, pertenece al window |
scroll |
Estamos haciendo scroll en la ventana o en un elemento div |
click |
Hacemos clic sobre un nodo |
dblclick |
Hacemos doble clic sobre un nodo |
mouseover |
Pasamos el ratón por encima del elemento |
mouseout |
El ratón sale del elemento |
change |
El valor de un campo de formulario cambia |
submit |
Un formulario es enviado hacia el servidor |
keydown, keyup |
Pulsamos una tecla del teclado. La tecla que se ha pulsado la podemos encontrar en la propiedad which, del objeto event pasado al manipulador |
error |
Se desencadena, por ejemplo, cuando desde el servidor una imagen no se carga |
3.8.Formularios
$('#id').val()
$('formulario#un').on('submit', function(){ // si validación correcta return true; // si hay errores en la validación // los podemos mostrar y se tiene que devolver false return false; }
3.9.AJAX
$.get( url, [ data ], success(data))
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Ejercicio de carga de ajax</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> <script> $(function(){ $('#bt').click(function(){ // 1 $.get('archivo.txt', {hola:3, mundo:4}, function(data){ // 2 $('#desti').html(data); // 3 }); }) }); </script> <style> #desti { color:blue; } </style> </head> <body> <p>Al apretar el botón, cargaremos dentro del párrafo azul, el contenido del archivo txt, del servidor.</p> < input type="button" id="bt" value="Carga" /> <p id="desti">Aquí cargaremos un contenido de con AJAX desde el servidor</p> < /body> </html>
3.10.Componentes (widgets)
3.11.Patrones de uso
$(documento).ready(function() { // código de programación })
$(function() { // código de programación })
$('#lelemtn') .css('color', 'black') .on('click', alferclic) .on('mouseover', rollover)
4.Frameworks JavaScript
4.1.Angular
-
X (Major): indica cambios rupturistas
-
Y (Minor): indica cambios compatibles con la versión anterior
-
Z (Patch): indica resoluciones de bugs (compatibles)
4.1.1.Características de Angular
-
Aplicaciones web progresivas: Permiten utilizar las capacidades modernas de las aplicaciones sobre plataforma web para ofrecer experiencias similares en aplicaciones de escritorio. Estas permiten una instalación rápida, en pocos pasos y sin necesitar una conexión a internet.
-
Aplicaciones nativas: Podemos escribir aplicaciones móviles nativas combinando Angular con Ionic Framework, NativeScript y React Native, entre otras.
-
Escritorio: También permite crear aplicaciones instalables para escritorios de Mac, Windows y Linux utilizando los mismos métodos de Angular empleados para desarrollar sobre plataformas web. Por otro lado, también posee la capacidad de acceder a las API nativas del sistema operativo.
-
Generación de código: Angular convierte nuestras plantillas en código altamente optimizado para las máquinas virtuales de JavaScript de hoy en día, ofreciéndonos todas las ventajas del código escrito a mano con la productividad de un framework.
-
Universal: Ejecuta la primera vista de tu aplicación en NODE.JS, .NET, PHP, y otros servidores para su renderizado de forma casi instantánea obteniendo solo HTML y CSS. También abre posibilidades para la optimización del SEO de la aplicación, algo que en la versión anterior resultaba más problemático.
-
División del código: Las aplicaciones de Angular se cargan rápidamente gracias al nuevo encaminador de componentes. Este ofrece una división automática de códigos para que los usuarios solo carguen el código necesario para procesar la vista que piden.
-
Reactivo: Todas las mejoras en el diseño mejoran el rendimiento general, pero la más crítica es la detección de cambios en la vista que antes se hacía con un ciclo de enviado a diario que consumía muchos ciclos de CPU, y ahora se implementa con un sistema reactivo que supone una muy importante mejora de rendimiento.
-
Plantillas: Permite crear rápidamente vistas de interfaz de usuario con una sintaxis de plantilla simple y potente.
-
Angular CLI: Las herramientas de línea de comandos nos permitirán empezar a desarrollar rápidamente, añadir componentes y realizar tests, así como previsualizar de forma instantánea nuestra aplicación.
-
IDE: Ofrece sugerencias de código inteligente, detección de errores y otras informaciones cuando se integra en la mayoría de los editores populares e IDE.
-
Testing: Utiliza Karma y Jasmine para las pruebas de unidad (unit tests) para saber si se han roto cosas cada vez que guardamos nuestros cambios. También es posible implementar tests de aceptación de selenium con Protractor para hacer que nuestras pruebas de escenarios corran más rápido y de manera estable.
-
Animación: Permite crear animaciones complejas y de alto rendimiento con muy poco código a través de la intuitiva API de Angular.
-
Accesibilidad: Posee características para crear aplicaciones accesibles con los componentes disponibles por ARIA (2) (MDN web docs).
-
Integración con otras tecnologías: Una de sus fortalezas es que se integra a la perfección con otras tecnologías que permiten crear web componentes como: React (Facebook), Polymer (Google) y X-Tag (Microsoft).
4.2.VueJS
-
Proporciona componentes visuales de forma reactiva. Piezas de UI bien encapsuladas que exponen una API con propiedades de entrada y emisión de eventos. Los componentes reaccionan ante eventos masivos sin que el rendimiento se vea perjudicado.
-
Cuenta con conceptos de directivas, filtros y componentes bien diferenciados.
-
La API es pequeña y fácil de utilizar.
-
Utiliza Virtual DOM. Las operaciones más costosas en JavaScript suelen ser las que manipulan el DOM. VueJS por su naturaleza reactiva necesita hacer cambios constantemente, pero para agilizar esta tarea cuenta con una copia virtual que se encarga de ir cambiando las partes necesarias.
-
Externaliza el encaminamiento y la gestión de estado en otras librerías.
-
Renderiza templates a pesar de soportar JSX. JSX es el lenguaje que usa React para renderizar la estructura de un componente. Es una especie de HTML + JS + extras que permite escribir plantillas HTML con más potencia. VueJS apoya a JSX, pero entiende que es mejor usar plantillas puras en HTML por su legibilidad y por la posibilidad de usar herramientas de terceros que trabajen con estas plantillas más estándar. De este modo, el desarrollador puede escoger el sistema que más le convenga.
-
Permite focalizar CSS para un componente específico. Permite crear contextos específicos para los componentes sin perder potencia en cuanto a las reglas de CSS.
-
Cuenta con un sistema de efectos de transición y animación.
-
Permite renderizar componentes para entornos nativos (Android e iOS).
-
Sigue un flujo one-way data-binding para la comunicación entre componentes.
-
Sigue un flujo doble-way data-binding para la comunicación de modelos dentro de un componente aislado.
-
Tiene soporte para TypeScript. Cuenta con decoradores y tipos definidos de manera oficial y son descargados junto con la librería. +
-
Tiene soporte para ES6.
-
Tiene soporte a partir de Internet Explorer 9.
-
Permite renderizar las vistas en servidor. Los SPA y los sistemas de renderizado de componentes en JavaScript tienen el problema de que muchas veces son difíciles de utilizar por robots como los de Google, por lo tanto, el SEO de nuestra web o aplicación se puede ver perjudicado. VueJS permite mecanismos para que los componentes puedan ser renderizados en tiempos de servidor.
-
Es extensible. Vue se puede extender mediante plugins.
4.3.React
-
Composición de componentes: En programación funcional se pasan funciones como parámetros para resolver problemas más complejos, creando lo que se conoce como composición funcional. En React podemos aplicar este patrón mediante la composición de componentes, unos componentes que encapsulan un comportamiento, una vista y un estado. Crearemos componentes para resolver pequeños problemas, que para ser pequeños son más fáciles de resolver y más adelante resultan más fáciles de visualizar y comprender. Después, unos componentes se apoyarán en otros para resolver problemas mayores y al final la aplicación será un conjunto de componentes que trabajan entre sí. Este modelo es fácil de mantener, de depurar, de escalar, etc.
-
Desarrollo declarativo: Con librerías más sencillas como jQuery se realiza un estilo de programación imperativo, es decir, se realizan scripts que paso por paso tienen que informar sobre qué acciones se tienen que realizar en el DOM, especificando con detalle cada uno de los cambios. La forma imperativa de declarar obliga a escribir mucho código, porque cada pequeño cambio se tiene que definir en un script y cuando el cambio puede ser provocado desde muchos lugares. El estilo de React es más declarativo, en él contamos con un estado de la aplicación, y sus componentes reaccionan ante el cambio de este estado. Los componentes tienen una funcionalidad dada y cuando cambia una de sus propiedades, ellos producen un cambio.
-
Flujo de datos unidireccional: Esta es otra acción que facilita React, aunque no es exclusivo. En este modelo de funcionamiento, los componentes de orden superior propagan datos a los componentes de orden inferior. Los de orden inferior trabajarán con estos datos y cuando cambia su estado podrán propagar eventos hacia los componentes de orden superior para actualizar sus estados.
-
Mejor rendimiento gracias al DOM virtual: El rendimiento a la hora del renderizado de la aplicación se consigue mediante el DOM virtual. No es que React no opere con el DOM real del navegador, pero sus operaciones las realiza antes sobre el DOM virtual, que es mucho más rápido. El DOM virtual está cargado en memoria y gracias a la herramienta que diferencia entre este y el real se actualiza el DOM del navegador, permitiendo actualizaciones de hasta 60 frames por segundo, y por lo tanto, producen aplicaciones muy fluidas, con movimientos suavizados.
-
Isomorfismo: Es la capacidad de ejecutar el código tanto en el cliente como en el servidor. También se conoce como «JavaScript Universal». Sirve principalmente para solucionar problemas de posicionamiento tradicionales de las aplicaciones JavaScript.
-
Elementos y JSX: ReactJS no devuelve HTML. El código embebido dentro de JavaScript parece HTML pero realmente es JSX. Son como funciones JavaScript, pero expresadas mediante una sintaxis propia de React llamada JSX. Lo que produce son elementos en memoria y no elementos del DOM tradicional, con lo cual las funciones no ocupan tiempos al producir pesados objetos del navegador sino simplemente elementos de un DOM virtual.
-
Componentes con y sin estado: React permite crear componentes de varias maneras, pero hay una diferencia entre componentes con y sin estado. Los componentes stateless son los componentes que no tienen estado (no guardan datos en su memoria). Esto no quiere decir que no puedan recibir valores de propiedades, pero estas propiedades siempre las llevarán en las vistas sin producir un estado dentro del componente. Estos componentes sin estado se pueden escribir con una sencilla función que devuelve el JSX que el componente tiene que representar en la página. Por otro lado, los componentes statefull son algo más complejos porque son capaces de guardar un estado y mantienen lógica de negocio generalmente. Su principal diferencia es que se escriben en el código de una manera más compleja, generalmente por medio de una clase ES6, en la que podemos tener atributos y métodos para realizar todo tipo de operaciones.
-
Ciclo de vida de los componentes: React implementa un ciclo de vida para los componentes. Son métodos que se ejecutan cuando pasan cosas comunes con el componente, que nos permiten subscribir acciones cuando se produce una inicialización, se recibe la devolución de una promesa, etc.
-
Comportamiento con otras librerías: A pesar de que React no se encarga de todas las partes necesarias para hacer una aplicación web compleja, la serie de componentes y herramientas basadas en React nos permiten encontrar una alternativa capaz de hacer cualquier cosa que podríamos hacer con otro framework más complejo. Por otro lado, React solapa completamente las funcionalidades de jQuery, por lo que resulta una evolución natural para todos los sitios que usan esta librería. Podrían convivir pero no es demasiado necesario y a la vez recargaría un poco la página, de forma que tampoco sería muy recomendable.
4.4.Vanilla JavaScript
5.Typescript
5.1.Superset
5.2.Instalación
npm install -g typescript
5.3.Crear y compilar un archivo ts
tsc nombredelfichero.ts