Post on 05-Jul-2015
description
ECMASCRIPT 6
Noviembre 2014
@LuisCalvoDiaz
@NachoNavaReus
• Brendan Eich (Netscape) creó un lenguaje en 1995 para el cliente que denominó Mocha y luego Livescript.
• Netscape firma con Sun Microsystem y cambia de nombre a Javascript antes del lanzamiento en Netscape Navigator 2.0. (Marzo 1996)
• Microsoft lanzó JScript con Internet Explorer 3. Dialecto compatible que añadía alguna funcionalidad más. (Agosto 1996)
• Envío de especificación Javascript 1.1 al organismo ECMA (European Computer Manufacturers Association) en Noviembre 1996.
• TC39 creó ECMA-262 (Junio 1997)
Introducción
HiSTORIA
Introducción
Versiones
Versión Fecha Detalles
1.0 Junio 1997
2.0 Junio 1998 Cambios para conservar la especificación con la ISO/IEC 16262
3.0 Diciembre 1999 Se añaden expresiones regulares, se mejora el manejo de string, try/catch, y algunas otras mejoras
4.0 Abandonada Edición abandonada debido a diferencias referentes a la complejidad del lenguaje.
5.0 Diciembre 2009 ‘strict mode’, aclara ambigüedades de la 3.0, añade algunas características como getters, setters, soporte para JSON, ...
5.1 Junio 2011 Edición alineada con la tercera edición de ISO/IEC 16262:2011
6 Work in progress A ello vamos...
7 Work in progress Está muy verde aún.
NUEVAS
VARIABLES
CONST
LET
1
Ecmascript 6 : Variables
Const: IE11, Firefox 11+, Chrome 19+, Opera 17+
// x: constante
const x = 20;
console.log(x); // 20
x = 1;
console.log(x); // 20
// No cam bia el valor de x
Hasta ahora nos hemos visto obligados a : var CONSTANTE = 20;
Ecmascript 6 : Variables
Let: IE11, Firefox 28+, Chrome* 17+, Opera* 17+
var a = 1;
var b = 2;
{
var c = 3;
}
console.info(a, b, c); // 1 2 3
let a = 1;
let b = 2;
{
let c = 3;
}
console.info(a, b, c);
// ReferenceError: c is not defined
var i = "i";
var tem poral = "tem poral";
for(let i = 1; i != false; i = false){
let tem poral = 10;
}
console.log(i, tem poral); // i tem poral
DEFINICIONES
DE MÉTODOS
get, set
functionName()
2
Ecmascript 6 : Definiciones de métodos
name() : No soportada aún.
var BigLoco = {
locoNam e: 'Gordon',
get nam e() { return this.locoNam e; },
set nam e(n) { this.locoNam e = n }
};
console.log(BigLoco.nam e); // 'G ordon'
ES5.1 : get() y set()
var Steam Engine = {
color: 'blue',
get nam e() { return 'Thom as' },
start() { console.log('Hurry up!'); },
stop() { console.log('G ood job!'); }
};
console.log('M y nam e is', Steam Engine.nam e);
Steam Engine.start();
Steam Engine.stop();
ES6 : Cualquier función
NUEVA SINTAXIS
DE FUNCIONES
Arrow ( => )
Valores por defecto
function(...values)
3
Ecmascript 6 : Nueva sintaxis de funciones
Función Arrow ( => ): Firefox 22+
// First syntax
([param ] [, param ]) = > { statem ents }
// Second syntax
param = > expression
var num bers = [10, 21, 15, 8];
// prints "[true, false, false, true]"
console.log(
num bers.m ap(function(num ber) {
return num ber % 2 = = = 0;
})
);
var num bers = [10, 21, 15, 8];
// prints "[true, false, false, true]"
console.log(
num bers.m ap(num ber = > num ber % 2 = = = 0)
);
Ecmascript 6 : Nueva sintaxis de funciones
Función Arrow ( => ): Firefox 22+
var jane = {
nam e: "Jane",
logHello: function (friends) {
friends.forEach(function (friend) {
console.log(this.nam e + " says hello to " .
friend.nam e);
friend.done = true;
});
}
}
var jane = {
nam e: "Jane",
logHello: function (friends) {
friends.forEach((friend) = > {
this.nam e + " says hello to " + friend;
friend.done = true;
});
}
}
También nos ayuda a solucionar problemas referentes a this.
Ecmascript 6 : Nueva sintaxis de funciones
Valores por defecto: Firefox 15+
function Person(nam e) {
// Set default values
nam e = nam e || 'Juan';
this.toString = function() {
return 'M y nam e is ' + nam e;
}
};
function Person(nam e = 'Juan') {
this.toString = function() {
return 'M y nam e is ' + nam e;
}
};
function prod(num ber1 = 1, num ber2) { }
function Person(nam e, surnam e, usernam e = nam e + ' ' + surnam e) { }
Ecmascript 6 : Nueva sintaxis de funciones
Rest parameter: Firefox 15+
function presentation(nam e, surnam e, ...otherInfo) {
console.log('M i nom bre es ' + nam e + ' ' + surnam e);
if (otherInfo.length > 0) {
console.log('O tra inform ación: ' + otherInfo.join(', '));
}
}
presentation('Juan', 'Rodríguez');
// "M i nom bre es Juan Rodríguez"
presentation('Nacho', 'Navarro', 'hom bre', 'Español', 'Desarrollador W eb');
// "M y nam e is Nacho Navarro"
// "O tra inform ación: hom bre, Español, Desarrollador w eb"
Permite introducir un número arbitrario de parámetros en una función.
ITERATORS, ITERABLE
GENERATORS
ITERATORS
ITERABLES
FOR...OF
GENERATORS
4
Ecmascript 6 : Iterators, generators.
Iterators
Objetos con un solo método: next(), que puede devolver:
● { done: false, value: elem }
● { done: true[, value: retVal] }
function createArrayIterator(arr) {
let index = 0;
return {
next() {
if (index < arr.length) {
return { done: false, value: arr[index+ + ] };
} else {
return { done: true };
}
}
}
}
Ecmascript 6 : Iterators, generators.
Iterables
function createIterableArray(arr) {
return {
[Sym bol.iterator]() { // protocol: iterable
return this.iterator; // an iterator!
},
iterator: {
let index = 0;
return {
next() { // protocol: iterator
...
}
}
}
}
}
Las estructuras de datos sobre las que se puede iterar se conocen como ‘iterables’ en ECMAScript 6.
next() {
if (index < arr.length) {
return { done: false, value: arr[index+ + ] };
} else {
return { done: true };
}
}
Ecmascript 6 : Iterators, generators.
The for-of loop: Firefox 13+, Chrome+ 38, Opera+ 25
function createIterableArray(arr) {
return {
[Sym bol.iterator]() { // protocol: iterable
return this.iterator; // an iterator!
},
iterator: {
...
}
}
}
const arr = [ 'red', 'green', 'blue' ];
for(let x of createIterableArray(arr)) {
console.log(x);
}
El nuevo bucle for-of trabaja con iterables.
Ecmascript 6 : Iterators, generators.
The for-of loop: Firefox 13+, Chrome+ 38, Opera+ 25
En ECMAScript 6, array es iterable.
let arr = ['foo', 'bar', 'baz'];
for (let elem ent of arr)) {
console.log(elem ent);
}
//foo
//bar
//baz
Ecmascript 6 : Iterators, generators.
Generators: Firefox 27+, Chrome 21+, Opera 17
function* generatorFunction() {
yield 1;
yield 2;
}
> let genO bj = generatorFunction();
> genO bj.next()
{ done: false, value: 1 }
> genO bj.next()
{ done: false, value: 2 }
> genO bj.next()
{ done: true }
Generators son un tipo especial de funciones que pueden ser suspendidas y reanudadas
Ecmascript 6 : Iterators, generators.
Generators (ii)
function* fibonacci() {
let [prev, curr] = [0, 1];
while (1) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
let seq = fibonacci();
console.log(seq.next()); // { done: false, value: 1}
console.log(seq.next()); // { done: false, value: 2}
console.log(seq.next()); // { done: false, value: 3}
console.log(seq.next()); // { done: false, value: 5}
console.log(seq.next()); // { done: false, value: 8}
)
Ecmascript 6 : Iterators, generators.
Generators (iii): Recursividad
function recursivelyIterateThrough( som ething ) {
if ( tim eToStop() ) {
return w hatever();
}
recursivelyIterateThrough( m oreW ork );
}
function* recursivelyIterateThrough( som ething ) {
if ( tim eToStop() ) {
yield w hatever();
}
yield* recursivelyIterateThrough( m oreW ork );
}
Ecmascript 6 : Iterators, generators.
Generators (iv): Recursividad
function* iterTree(tree) {
if (Array.isArray(tree)) {
for(let i= 0; i < tree.length; i+ + ) {// inner node
yield* iterTree(tree[i]); // (*) recursion
}
} else { // leaf
yield tree;
}
}
const tree = [ 'a', ['b', 'c'], ['d', 'e'] ];
for(let x of iterTree(tree)) {
console.log(x);
}
//”a” “b” “c” “d” “e”
Métodos
de Array
Array.from.
Array.find.
Array.findIndex.
Array.prototype.keys.
Array.prototype.values.
Array.prototype.fill
5
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.find(): Firefox 24+, Chrome 35+, Opera 22+ (EEJ).
Devuelve el valor si lo encuentra, o undefined.
Array.prototype.find(callback[, thisArg])
Callback parámetros:
● element
● index
● array
var array = [1, 2, 3, 4];
var result = array .find(function(elem) {return elem % 2 === 0;});
//imprime 2 porque es el primer elemento par
console.log(result);
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.findIndex(): Firefox 24+, Chrome 35+, Opera 22+ (EEJ).
Igual que Array.prototype.find(), pero devuelve la posición.
Array.prototype.findIndex(callback[, thisArg])
Callback parámetros:
● element
● index
● array
var array = [1, 2, 3, 4];
var result = array .findIndex(function(elem) {return elem % 2 === 0;});
//imprime 1 porque es el primer elemento par
console.log(result);
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.values(): Firefox 28+, Chrome 35+, Opera 22+ (EEJ).
Devuelve un nuevo Array Iterator que contiene los valores del array.
Array.prototype.values()
var array = [8, 55, 43, 14];
var iterator = array .values();
// Imprime "8, 55, 43, 14", una cada vez
var element= iterator.next();
while(!element.done) {
console.log(element.value);
element= iterator.next();
}
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.keys(): Firefox 28+, Chrome 35+, Opera 22+ (EEJ).
Igual que Array.prototype.values(), pero devuelve un Array Iterator que contiene las claves del array
Array.prototype.keys()
var array = [8, 55, 43, 14];
var iterator = array .keys();
// Imprime "0, 1, 2, 3", una cada vez
var index = iterator.next();
while(!index.done) {
console.log(index.value);
index = iterator.next();
}
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.keys(): Firefox 31+, Chrome 37+, Opera 24+ (EEJ).
Array.prototype.fill(value[, start[, end]]);
var array = new Array(6);
// Esta sentencia rellena posiciones desde la 0 hasta la 2.
array .fill(1, 0, 3);
// Esta sentencia rellena el array desde la posición 3 hasta el final del mismo.
array .fill(2, 3);
// imprime [1, 1, 1, 2, 2, 2]
console.log(array );
Default values:
● start = 0.
● end = Array.length.
● Si start o end son negativos, las posiciones son calculadas desde el final del array
Ecmascript 6 : Nuevos métodos de Array
Array.prototype.fill(): Firefox 31+, Chrome 37+, Opera 24+ (EEJ).
Array.prototype.fill(value[, start[, end]]);
var array = new Array(6);
// Esta sentencia rellena posiciones desde la 0 hasta la 2.
array .fill(1, 0, 3);
// Esta sentencia rellena el array desde la posición 3 hasta el final del mismo.
array .fill(2, 3);
// imprime [1, 1, 1, 2, 2, 2]
console.log(array );
Default values:
● start = 0.
● end = Array.length.
● Si start o end son negativos, las posiciones son calculadas desde el final del array
MÓDULOS EN
ECMASCRIPT 6
COMMONJS & AMD
IMPORT
EXPORT
META-DATA
BENEFICIOS
6
Javascript no tiene soporte nativo para módulos. Destacan dos workarounds:
Módulos
COMMONJS
● Sintaxis compacta.
● Diseñado para carga síncrona.
● Soporte dependencias cíclicas.
● Principal uso: Servidores.
● Implementación dominante: NodeJs.
AMD
● Sintaxis más complicada.
● Diseñado para carga asíncrona.
● No soporta dependencias cíclicas
● Principal uso: Browsers.
● Implementación más popular: RequireJs.
Módulos
Exports
//------ lib.js ------
export const sqrt = M ath.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ m ain.js ------
im port { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
//------ m ain.js ------
im port * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
Módulos
Default Export
//------ m yFunc.js ------
export default function () { ... };
//------ m ain1.js ------
im port m yFunc from 'm yFunc';
m yFunc();
//------ M yClass.js ------
export default class { ... };
//------ m ain2.js ------
im port M yClass from 'M yClass';
let inst = new M yClass();
Sólo puede haber un default export por módulo.
Módulos
Multiple exports con un default export
//------ underscore.js ------
export default function (obj) {
...
};
export function each(obj, iterator, context) {
...
}
//------ m ain.js ------
im port _, { each as loop} from 'underscore';
Módulos
Más sobre ‘exports’
export var m yVar1 = ...;
export let m yVar2 = ...;
export const M Y_CO NST = ...;
export function m yFunc() {
...
}
export function* m yG eneratorFunc() {
...
}
export class M yClass {
...
}
const M Y_CO NST = ...;
function m yFunc() {
...
}
export { M Y_CO NST as THE_CO NST, m yFunc as theFunc };
Existen dos maneras de exportar los elementos del módulo:
● Marcar declaraciones con la palabra clave export.
● Listar todo lo que quieras exportar al final del módulo.
Módulos
Importando
// Default exports and nam ed exports
im port theDefault, { nam ed1, nam ed2 } from 'src/m ylib';
im port theDefault from 'src/m ylib';
im port { nam ed1, nam ed2 } from 'src/m ylib';
// Renam ing: im port nam ed1 as m yNam ed1
im port { nam ed1 as m yNam ed1, nam ed2 } from 'src/m ylib';
// Im porting the m odule as an object
// (w ith one property per nam ed export)
im port * as m ylib from 'src/m ylib';
// O nly load the m odule, don’t im port anything
im port 'src/m ylib';
Módulos
Re-exportando
Re-expotar es añadir otras exportaciones de otros módulos a las de nuestro módulo.
// Podem os expotar todo el m ódulo
export * from 'src/other_m odule';
// Podem os ser m ás selectivos
export { foo, bar } from 'src/other_m odule';
// Exportar foo de otro m ódulo, com o m yFoo
export { foo as m yFoo, bar } from 'src/other_m odule';
Módulos
Meta data
Tenemos acceso a ciertos meta-datos del módulo a través de ‘this’.
im port { nam e, url } from this m odule;
console.log(url);
//Tam bién podem os acceder vía objeto.
im port * as m etaData from this m odule;
console.log(m etaData.url);
Módulos
API de carga de módulos
Nos permite trabajar asíncronamente y configurar la carga de un módulo.
System .im port('som e_m odule')
.then(som e_m odule = > {
...
})
.catch(error = > {
...
});
System.import() te permite usar módulos dentro de la etiqueta <script>.
Prom ise.all(
['m odule1', 'm odule2', 'm odule3']
.m ap(x = > System .im port(x)))
.then(function ([m odule1, m odule2, m odule3]) {
});
Módulos
Beneficios
● Sintaxis elegante.
● Soporta dependencias cíclicas.
● Trabaja síncrona y asíncronamente.
● No más UMD (Universal Module Definition).
NUEVOS MÉTODOS
DE NUMBER
Number.isInteger()
Number.isNan()
Number.isFinite()
Number.isSafeInteger()
Number.parseInt()
7
Ecmascript 6 : Number
Number.isInteger(): Firefox 16+, Chrome 34+, Opera21*+
// true
console.log(Num ber.isInteger(19));
// false
console.log(Num ber.isInteger(3.5));
// false
console.log(Num ber.isInteger([1, 2, 3]));
Num ber.isInteger(value)
Ecmascript 6 : Number
Number.isNaN(): Firefox 16+, Chrome 19+, Opera17*+
console.log(w indow .isNaN(0/0));
console.log(w indow .isNaN('test'));
console.log(w indow .isNaN(undefined));
console.log(w indow .isNaN({prop: 'value'}));
window.isNaN() ya existía. Pero...
// true
// true
// true
// true
Ecmascript 6 : Number
Number.isNaN(): Firefox 16+, Chrome 19+, Opera17*+
console.log(Num ber.isNaN(0/0));
console.log(Num ber.isNaN(NaN));
console.log(Num ber.isNaN(undefined));
console.log(Num ber.isNaN({prop: 'value'}));
Number.isNaN() se comporta de forma diferente.
// true
// true
// false
// false
Ecmascript 6 : Number
Number.isFinite(): Firefox 16+, Chrome 19+, Opera17*+
console.log(w indow .isFinite(10));
console.log(w indow .isFinite(Num ber.M AX_VALUE));
console.log(w indow .isFinite(null));
console.log(w indow .isFinite([]));
window.isFinite() también existía.
// true
// true
// true
// true
Ecmascript 6 : Number
Number.isFinite(): Firefox 16+, Chrome 19+, Opera17*+
console.log(Num ber.isFinite(10));
console.log(Num ber.isFinite(Num ber.M AX_VALUE));
console.log(Num ber.isFinite(null));
console.log(Num ber.isFinite([]));
Num ber.isFinite(value) se comporta de forma diferente.
// true
// true
// false
// false
Ecmascript 6 : Number
Number.isSafeInteger(): Firefox 16+, Chrome 19+, Opera17*+
● Safe integers: Aquellos enteros desde el -(2 - 1) inclusive hasta el 2 - 1
● Num ber.isSafeInteger(value)
console.log(Num ber.isSafeInteger(5)); // im prim e "true"
console.log(Num ber.isSafeInteger('19')); // im prim e "false"
console.log(Num ber.isSafeInteger(M ath.pow (2, 53))); // im prim e "false"
console.log(Num ber.isSafeInteger(M ath.pow (2, 53) - 1)); // im prim e "true"
53 53
Ecmascript 6 : Number
Number.parseInt(), Number.parseFloat: Firefox 16+, Chrome 19+, Opera17*+
Num ber.parseInt(valor [, base])
// im prim e "-3"
console.log(Num ber.parseInt('-3'));
// im prim e "4"
console.log(Num ber.parseInt('100', 2));
// im prim e "NaN"
console.log(Num ber.parseInt('test'));
// im prim e "NaN"
console.log(Num ber.parseInt({}));
// im prim e "42.1"
console.log(Num ber.parseFloat('42.1'));
// im prim e "NaN"
console.log(Num ber.parseFloat('test'));
// im prim e "NaN"
console.log(Num ber.parseFloat({}));
Num ber.parseFloat(valor)
MAP
PROTOTYPE
MAP PROTOTYPE
8
Map
Map: Firefox, Chrome* , Opera*
var array = [['key1', 'value1'], ['key2', 100]];
var m ap = new M ap(array);
console.log(m ap.get('key1')); //‘value1’
m ap.set({'a' : 'b'}, 'tres');
console.log(m ap.get({'a' : 'b'})); //undefined;
var array2 = ['lentejas', 'lim on'];
m ap.set(array2, 'exquisito');
console.log(m ap.get(array2)); //exquisito;
console.log(m ap.size); //4;
for(let x of m ap){
console.log(x);
}
for(let x of m ap.values()){
console.log(x);
}
m ap.forEach(function(value, key, m ap){
console.log(value);
});
m ap.delete(array2); //true;
m ap.has('no estoy'); //false;
CLASS,
SUBCLASS
CLASS
SUBCLASS
9
Class, subclass
Class, class extends
// Superclass
class Person {
constructor(nam e) {
this.nam e = nam e;
}
describe() {
return "Person called " + this.nam e;
}
}
// Subclass
class Em ployee extends Person {
constructor(nam e, title) {
super.constructor(nam e);
this.title = title;
}
describe() {
return super.describe() + " (" + this.title + ")";
}
}
Class, subclass
Uso de Class
let jane = new Em ployee("Jane", "CTO ");
jane instanceof Person; //true
jane instanceof Em ployee //true
jane.describe() //Person called Jane (CTO )
ES6
PROXY
ES6 PROXY
10
EC6 PROXY
var designer= { nam e:'M ontalvo', salary: 50 };
var interceptor = {
set: function (receiver, property, value) {
console.log(property, 'is changed to', value);
receiver[property] = value;
}
};
designer = new Proxy(designer, interceptor);
designer .salary = 60;
//salary is changed to 60
Operation Intercepted as
proxy[name] handler.get(proxy, name)
proxy[name] = val handler.set(proxy, name, val)
name in proxy handler.has(name)
delete proxy[name] handler.delete(name)
for (var name in proxy) {...} handler.iterate()
Object.keys(proxy) handler.keys()
Recursos y fuentes
Recursos:
http://addyosmani.com/blog/ecmascript-6-resources-for-the-curious-javascripter/
Fuentes:
https://developer.mozilla.org
http://www.sitepoint.com/
https://github.com/lukehoban/es6features
http://ariya.ofilabs.com/
http://www.2ality.com/
http://addyosmani.com/
https://leanpub.com/
Recursos y fuentes
Esto es todo
MUCHAS GRACIAS :)
Contacto:
@LuisCalvoDíaz
lcalvo@paradigmatecnologico.com
@NachoNavaReus
inavarro@stratio.com