5
¿Quién soy?
developerFormación universitaria y
en empresas
Desarrollador Media ServerWebRTC Open Source
14
Características Imperativo Funcional (expresiones lambda) Recolector de basura Tipos estáticos Orientado a objetos (con clases) Modularidad con paquetes (y con .jars)
25
Características Imperativo Funcional Recolector de basura Tipado dinámico Orientado a objetos (con prototipos) Sin modularidad
ES5
26
Tipado dinámico El compilador no te ayuda
Hay que ejecutar los tests (si tienes) El IDE tampoco te ayuda
No se puede refactorizar de forma automática El autocompletar es muy limitado La documentación integrada sólo aparece en
casos muy evidentes No se puede navegar a la implementación
ES5
27
Orientado a objetoscon prototipos
Existen 3 formas diferentes de implementar “clases”
Prototipos “a mano” Simulación de clases con librerías Patrón módulo usando clousures
ES5
28
Orientado a objetoscon prototipos
ES5
function Empleado(nombre, salario){
this.nombre = nombre; this.salario = salario;}
Empleado.prototype.getNombre = function(){ return nombre;} Empleado.prototype.toString = function(){ return "Nombre:"+this.nombre+", Salario:"+this.salario;}
var empleado = new Empleado("Pepe", 700);console.log( empleado.toString() );
29
Orientado a objetoscon prototipos
La herencia es “hacky” (aunque ellos dirán que no se usa mucho...)
Los patrones de diseño OO no se pueden aplicar directamente (ya que te los has aprendido...)
ES5
30
Sin modularidad Para independizar código tienes que usar
patrones basados en funciones O usar AMD, CommonJS, UMD...
ES5
(function() {
var variableTemporal = "a"; //Otro código…
}());
Immediately-Invoked Function Expression (IIFE)
31
y otras lindezas...¿this y that?
ES5
function Empleado(nombre, sueldo){ this.nombre = nombre; this.sueldo = sueldo;}
Empleado.prototype.alertaAlPulsar(button){
button.onclick = function(){ alert(this.nombre+" "+this.sueldo); }}
ERROR: this apunta al objeto en el que se ha generado el evento
32
y otras lindezas...WAT / === / !==
ES5
https://www.destroyallsoftware.com/talks/wat
41
Google Web Toolkit En 2006 Google saca una herramienta para
convertir código Java a código JavaScript
JS ultraoptimizado y compatible con los
browsers “incompatibles” del momento
Librería de widgets
42
Google Web Toolkit Pero...
● Muy acoplado al backend escrito en Java (con su
propio protocolo de comunicación)
● Desarrollo muy pesado (compilador tardaba,
plugins para ejecutar Java en el navegador…)
● Complicado usar librerías JavaScript desde código
Java...
44
Nuevo GWT (2.8 beta) Desarrollado por la comunidad
Mucho más ligero, sin plugins en browsers
Mejor integración Java y JavaScript
No acoplado a backend Java (clientes REST)
Soporta Java 8 (lambda)
45
Nuevo GWT (2.8 beta) No es una tecnología de front-end genérica Lo usaría solo para portar código Java
existente a front-end con poco coste
https://news.ycombinator.com/item?id=8554339
47
Deseos de un Javero desarrollando web frontend
Un lenguaje orientado a objetos con clases y herencia
Tipado estático Buenas herramientas con autocompletar,
refactoring, navegación…
49
Deseos de un Javero desarrollando web frontend
Plugin de eclipse / IntelliJ / Netbeans Que esté maduro y se use en producción (que
no sea un proyecto en github de cuatro frikis) Que haya buena documentación en la red,
libros, video cursos...
50
Deseos de un Javero desarrollando web frontend
Que pueda usar cualquier librería JavaScript directamente sin complicaciones
Que también lo usen los hipsters frontenders JavaScripters para que no me miren mal
Que esté apoyado por la comunidad y por las empresas
55
¿Qué es TypeScript? Un superconjunto de JavaScript que añade tipos
estáticos
Soporta orientación a objetos con clases y herencia
El compilador de TypeScript genera código JS que
se ejecuta en cualquier browser y en node.js
http://www.typescriptlang.org/ https://www.gitbook.com/book/basarat/typescript/details
57
¿Qué son ES6 y ES7?
ES6 es la última versión de JS (pero ningún navegador la entiende 100%)
A ES6 ahora le llaman ES2015 ES7 es la versión en desarrollo, aunque algunas
partes son bastante estables Algunas características de TypeScript se pueden
usar en JavaScript ES6
58
Más características de TS Funciones lambda (llamadas arrow functions) en
las que this no cambia de significado Módulos (exportar e importar elementos) Anotaciones Programación pseudo-síncrona con async / await Ámbito de variables de bloque (y error si se declara
dos veces) For each ...
62
Desde que llegó Nadella Microsoft está irreconocible
software libre
https://github.com/Microsoft/TypeScript
64
export class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string,salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
TypeScript
65
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
66
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
En Java las clases son públicas. En TypeScript las clases se exportan
67
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
En TS los tipos se ponen tras el nombre con : (dos puntos)
68
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
En TS el constructor es “constructor”
69
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
En TS los tipos se infieren (si quieres), incluso en el tipo que devuelven los métodos
70
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
private nombre:string; private salario:number;
constructor(nombre:string, salario:number){ this.nombre = nombre; this.salario = salario; }
getNombre(){ return this.nombre; }
toString(){ return "Nombre:"+this.nombre+ ", Salario:"+this.salario; }}
Clase en TypeScript
En TS siembre que quieras acceder a un elemento de la clase tendrás que usar this.
71
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
72
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
73
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
En Java las clases de la misma carpeta son del mismo paquete. En TS cada fichero es un módulo, por eso hay que importar desde otros ficheros
74
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
En TS las variables se declaran con let y tienen ámbito de bloque y no se pueden declarar dos veces. Se podría usar var (como JS), pero el ámbito sería la función y se podrían redeclarar
75
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
En TS las variables se pueden declarar con tipo (después de :), pero es opcional porque el tipo se infiere de la inicialización. En Java no lo veremos hasta Java 9 o Java 10
76
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
En Java usamos List y ArrayList generificados del API.En TS usamos el Array nativo de JS generificado por TS.
77
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
En Java List el método es “add”En el Array de JS el método es “push”
78
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
La sintaxis del foreach es muy parecida en Java y TS. En TS está basado en iteradores (como en Java)
79
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));emps.push(new Empleado('Juan', 200));
for(let emp of emps){ console.log(emp.getNombre());}
empleados.forEach(emp => { console.log(emp);});
TypeScript
Las expresiones lambda de Java se llaman arrow function en TS.Se diferencian en la “flecha” con – o con =
80
Lambdas / Arrow functions
int num = 0;
empleados.forEach(emp -> num++);
System.out.println(num);
Java
let num = 0;
empleados.forEach(emp => num++);
console.log(num);
TypeScript
En Java no se puede acceder a una variable que no sea final (declarada o efectiva) desde una lambda. En TS (como en JS) incluso se puede cambiar el
valor de la variable desde la propia arrow function
ERROR
81
Uso de this con la arrow function
function Empleado(nombre, sueldo){ this.nombre = nombre; this.sueldo = sueldo;}
Empleado.prototype.alerta(button){ var that = this; button.onclick = function(e){ alert(that.nombre); }}
En TS una arrow function permite usar this y siempre apunta al objeto (como Java). En JS si usas funciones this puede cambiar de valor (y es
necesario usar that)
export class Empleado {
private nombre:string, private sueldo:number){}
alerta(button:HTMLButtonElement){ button.onclick = e => { alert(this.nombre); } }}
JavaScript TypeScript
82
Anotaciones
import {Component} from 'angular2/core';
@Component({selector: 'app',templateUrl: 'app.component.html'
})export class AppComponent { }
83
Ventajas de TS respecto a JavaCaracterísticas que gustarán a los
desarrolladores Java porque simplifica patrones comunes en Java
84
Definición de atributos inicializados en constructor
class Animal {
private name:string;
constructor(name: string) { this.name = name;
}}
85
class Animal { constructor(private name: string) { }}
class Animal { private name:string; constructor(name: string) {
this.name = name; }}
class Animal { constructor(private name: string) { }}
En TS se puede declarar un atributo e inicializar su valor desde el constructor declarando ese atributo como parámetro del constructor y usando el modificar de visibilidad
Definición de atributos inicializados en constructor
86
class Foo { get bar() { return ...; }
set bar(bar: boolean) { ... }}
Getter / Setter con sintaxis de atributo
let foo = new Foo();
if(foo.bar){ foo.bar = false;}
87
class Foo { get bar() { return ...; }
set bar(bar: boolean) { ... }}
Getter / Setter con sintaxis de atributo
let foo = new Foo();
if(foo.bar){ foo.bar = false;}
88
class Animal { eat() { } }class Dog extends Animal { woof() { } }class Cat extends Animal { meow() { } }
let pet: Animal = ...;if (pet instanceof Dog) { pet.woof();} else if (pet instanceof Cat) { pet.meow();} else { pet.eat();}
Type guards Instanceof / typeof
Disponible también en
Animal
eat()
Animal
eat()
Dog
woof()
Animal
eat()
Cat
meow()
89
interface SquareConfig { color: string; width?: number;}
Objetos literales “tipados”
let config: SquareConfig;
config = {color: "black"};config = {color: "black", width: 20};
90
interface SquareConfig { color: string; width?: number;}
Objetos literales “tipados”
let config: SquareConfig;
config = {color: "black"};config = {color: "black", width: 20};
91
Programación asíncronaSimulación de sincronía con async / await
function loadData() { return getJSON('data.json') .then(data=>{
addHtmlToPage(data);
return data;
}).catch(err => { console.log(err) });}
async function loadData() { try {
let data = await getJSON('data.json');
addHtmlToPage(data); return data;
} catch(err){ console.log(err); } }
92
Programación asíncronaSimulación de sincronía con async / await
function loadData() { return getJSON('data.json')
.then(data=>{
addHtmlToPage(data);
return data;
}).catch(err => { console.log(err) });}
async function loadData() { try {
let data = await getJSON('data.json');
addHtmlToPage(data); return data;
} catch(err){ console.log(err); } }
94
Tipos unión
let id: string | number;
id = 3;...Id = “3”;
if(typeof id === “string”){ ...}
En JS es habitual que ciertas variables puedan tener la misma
información aunque se represente con varios “tipos”.
TS permite definir variables con varios tipos
95
Compatibilidad de tipos estructural
interface User { name: string;}
class Profile { constructor(public name:string){}}
let u: User;u = { name: "Pepe" };u = new Profile("Pepe");
96
interface User { name: string;}
class Profile { constructor(public name:string){}}
let u: User;u = { name: "Pepe" };u = new Profile("Pepe");
Compatibilidad de tipos estructural
Un objeto Profile puede asignarse a una variable
de tipo User porque tiene un atributo name
97
Sobrecarga de métodos “especial”class TestClass {
someMethod(p1: string): void; someMethod(p1: number, p2: string): void; someMethod(p1: string | number, p2?: string): void {
if (typeof p1 === "string"){ console.log("p1"); } else if(p2){ console.log("p2"); } }}
Dos métodos con el mismo nombre deben tener una única
implementación que detecte cual ha sido llamado.
La implementación tiene que cubrir todas las cabeceras
98
Limitaciones respecto a Java El código se ejecuta en una JavaScript VM, se
aplican todas las limitaciones del mismo No hay números de 64 bits (ni long ni double) No hay concurrencia con memoria
compartida El control del recolector de basura no permite
implementar weak / soft references
99
El lenguaje tiene buena pinta...¿Pero hay herramientas? Soporte? Librerías
compatibles? Lo usa alguien?
100
Editores / IDEsHay plugins para la mayoría de los editores / IDEs
Sublime Text Visual Studio Code WebStorm
104
Atom / atom-typescript
https://atom.io/packages/atom-typescript
105
Eclipse / typescript.java
https://github.com/angelozerr/typescript.java
106
Incluso los editores onlineTypeScript se puede transpilar a ES5 directamente en el propio browser
System.config({ transpiler: 'typescript', typescriptOptions: { emitDecoratorMetadata: true }, map: { app: "./src" }, packages: { app: { main: './main.ts', defaultExtension: 'ts' } }});
108
¿Quién usa TypeScript?
Seguro que 4 raros… porque ser JavaScripter y que te gusten el
tipado estático...
109
ngular 2TypeScript es el lenguaje recomendado
Prácticamente todos los ejemplos y tutoriales están implementados con TypeScript
110
Angular 2
import {Component} from 'angular2/core';
@Component({selector: 'app',templateUrl: 'app.html'
})export class AppComponent { name = 'Anybody'; }
app.component.ts
<h1>Hello {{name}}!</h1>
app.html
114
Los JavaScripters no se quejan mucho
Los tipos son opcionales La inferencia de tipos permite no tener que escribir
los tipos constantemente En realidad es JavaScript con más cosas, así que
todo lo conocido se puede aplicar Un mismo proyecto puede combinar JS y TS, lo que
facilita migrar un proyecto existente
116
A los que nos gusta nuestro compilador y nuestros IDEs por fin tenemos un lenguaje de verdad en el browser
Con este lenguaje desarrollar en Node.js y en el browser será como estamos acostumbrados
Muchos desarrolladores backend se pasarán a front con TypeScript
Existen muchas historias de éxito en la red
Top Related