58
ECMASCRIPT 6 Noviembre 2014 @LuisCalvoDiaz @NachoNavaReus

ECMAScript 6

Embed Size (px)

DESCRIPTION

Javascript no para de expandirse y avanzar. Y ahora, con la llegada de EcmaScript 6, ciertos workflows y la forma de escribir código va a cambiar. Ahora los javascripters vamos a tener más herramientas en nuestras manos. Ya hay frameworks populares como Angular que sus futuras versiones vendrán en EcmaScript 6. ¿Porqué no hecharle un vistazo al futuro? Charla impartida por Luis Calvo en la última edición de Codemotion (Madrid, Spain - Nov 21-22)

Citation preview

Page 1: ECMAScript 6

ECMASCRIPT 6

Noviembre 2014

@LuisCalvoDiaz

@NachoNavaReus

Page 2: ECMAScript 6

• 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

Page 3: ECMAScript 6

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.

Page 4: ECMAScript 6

NUEVAS

VARIABLES

CONST

LET

1

Page 5: ECMAScript 6

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;

Page 6: ECMAScript 6

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

Page 7: ECMAScript 6

DEFINICIONES

DE MÉTODOS

get, set

functionName()

2

Page 8: ECMAScript 6

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

Page 9: ECMAScript 6

NUEVA SINTAXIS

DE FUNCIONES

Arrow ( => )

Valores por defecto

function(...values)

3

Page 10: ECMAScript 6

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)

);

Page 11: ECMAScript 6

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.

Page 12: ECMAScript 6

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) { }

Page 13: ECMAScript 6

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.

Page 14: ECMAScript 6

ITERATORS, ITERABLE

GENERATORS

ITERATORS

ITERABLES

FOR...OF

GENERATORS

4

Page 15: ECMAScript 6

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 };

}

}

}

}

Page 16: ECMAScript 6

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 };

}

}

Page 17: ECMAScript 6

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.

Page 18: ECMAScript 6

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

Page 19: ECMAScript 6

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

Page 20: ECMAScript 6

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}

)

Page 21: ECMAScript 6

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 );

}

Page 22: ECMAScript 6

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”

Page 23: ECMAScript 6

Métodos

de Array

Array.from.

Array.find.

Array.findIndex.

Array.prototype.keys.

Array.prototype.values.

Array.prototype.fill

5

Page 24: ECMAScript 6

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);

Page 25: ECMAScript 6

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);

Page 26: ECMAScript 6

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();

}

Page 27: ECMAScript 6

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();

}

Page 28: ECMAScript 6

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

Page 29: ECMAScript 6

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

Page 30: ECMAScript 6

MÓDULOS EN

ECMASCRIPT 6

COMMONJS & AMD

IMPORT

EXPORT

META-DATA

BENEFICIOS

6

Page 31: ECMAScript 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.

Page 32: ECMAScript 6

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

Page 33: ECMAScript 6

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.

Page 34: ECMAScript 6

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';

Page 35: ECMAScript 6

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.

Page 36: ECMAScript 6

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';

Page 37: ECMAScript 6

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';

Page 38: ECMAScript 6

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);

Page 39: ECMAScript 6

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]) {

});

Page 40: ECMAScript 6

Módulos

Beneficios

● Sintaxis elegante.

● Soporta dependencias cíclicas.

● Trabaja síncrona y asíncronamente.

● No más UMD (Universal Module Definition).

Page 41: ECMAScript 6

NUEVOS MÉTODOS

DE NUMBER

Number.isInteger()

Number.isNan()

Number.isFinite()

Number.isSafeInteger()

Number.parseInt()

7

Page 42: ECMAScript 6

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)

Page 43: ECMAScript 6

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

Page 44: ECMAScript 6

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

Page 45: ECMAScript 6

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

Page 46: ECMAScript 6

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

Page 47: ECMAScript 6

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

Page 48: ECMAScript 6

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)

Page 49: ECMAScript 6

MAP

PROTOTYPE

MAP PROTOTYPE

8

Page 50: ECMAScript 6

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;

Page 51: ECMAScript 6

CLASS,

SUBCLASS

CLASS

SUBCLASS

9

Page 52: ECMAScript 6

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 + ")";

}

}

Page 53: ECMAScript 6

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 )

Page 54: ECMAScript 6

ES6

PROXY

ES6 PROXY

10

Page 55: ECMAScript 6

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()

Page 56: ECMAScript 6

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

Page 57: ECMAScript 6

Esto es todo

MUCHAS GRACIAS :)

Page 58: ECMAScript 6

Contacto:

@LuisCalvoDíaz

[email protected]

@NachoNavaReus

[email protected]