Skip to content

cerebrobr/es6features

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 

Repository files navigation

ECMAScript 6 git.io/es6features

Introduction

ECMAScript 6, também conhecido como ECMAScript 2015, é a mais recente versão do padrão ECMAScript. ES6 é um upgrade significativo na linguagem, é a primeira atualização desde que foi padronizada em 2009. Veja a implementação dessas funcionalidades nas principais engines de javascript no link Tabela de Compatibilidade do ECMAScript 6.

Veja o padrão ES6 para a especificação completa da linguagem ECMAScript 6.

ES6 inclui as seguintes novas funcionalidades:

Funcionalidades ECMAScript 6

Arrows

Arrows são abreviações de funções usando a sintaxe =>. Elas são semelhantes semanticamente ao recurso equivalente do C#, Java 8 e do CoffeeScript. Elas supotam expressões ou conjuntos de instruções. Ao conrário de function, arrows compartilham o mesmo this que o do código que o envolve.

// Expressões
var pares   = evens.map(v => v + 1);
var numeros = evens.map((v, i) => v + i);

// Conjuntos de instruções
numeros.forEach(v => {
  if (v % 5 === 0)
    listaCincos.push(v);
});

// "this" léxico
var joao = {
  _nome: "João",
  _amigos: [],
  listaAmigos() {
    this._amigos.forEach(f =>
      console.log( this._nome + " conhece " + f) );
  }
}

Classes

Classes ES6 são o padrão prototype melhorado. Ter uma única e conveniente forma declarativa fazem os padrões de classes mais fáceis de usar e icentivam a interoperabilidade. Classes suportam herança no modelo _ prototype, super calls, instânciamento, métodos estáticos e construtores.

class SkinnedMesh extends THREE.Mesh {
  constructor(geometry, materials) {
    super(geometry, materials);

    this.idMatrix = SkinnedMesh.defaultMatrix();
    this.bones = [];
    this.boneMatrices = [];
    //...
  }
  update(camera) {
    //...
    super.update();
  }
  static defaultMatrix() {
    return new THREE.Matrix4();
  }
}

Object Literals aprimorados

Object literals foram extendidos para facilitar definir o prototype construção, uma abreviação para definições foo: foo , definir métodos e fazer super calls. Juntos, eles também trazem literais de objeto e declarações de classe mais próximos, e deixam benefício design baseado em objeto de algumas das mesmas conveniências.

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand for ‘handler: handler’
    handler,
    // Methods
    toString() {
     // Super calls
     return "d " + super.toString();
    },
    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

Template Strings

Template strings tornam muito fácil gerar strings. É semelhante à interpolação de strings do Perl, Python e outros. Opcionalmente podemos adicionar uma tag que permitem a construção de uma string personalizada, evitando ataques com inserção de código ou montando estruturas de dados a partir do conteúdo de strings.

// Construção básica de uma string literal
`Em javascript '\n' é uam quebra de linha.`

// Strings multilinha
`Isto não funciona
 em Javascript.`

// Contruindo uma query ao DOM
`Olá ${nome}, como está o ${nome_amigo}?`

// Montar um prefixo de requisição HTTP para interpretar as substituições e construção
GET`http://foo.org/bar?a=${a}&b=${b}
    Content-Type: application/json
    X-Credentials: ${credentials}
    { "foo": ${foo},
      "bar": ${bar}}`(myOnReadyStateChangeHandler);

Destructuring

Destructuring permite vincular usando padrões de expressões regulares, com suporte à arrays e objects. Destructuring é fail-soft, semelhante à busca padrão em objetos foo["bar"], retornando o valor undefined quando não encontrado.

// list matching
var [a, , b] = [1,2,3];

// object matching
var { op: a, lhs: { op: b }, rhs: c }
       = getASTNode()

// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()

// Can be used in parameter position
function g({name: x}) {
  console.log(x);
}
g({name: 5})

// Fail-soft destructuring
var [a] = [];
a === undefined;

Default + Rest + Spread

Valores padrão nas chamadas de funções. Transformação de um array em argumentos consecutivos em uma chamada de função, Víncular parametros sequênciais em um array. Substitui a necessidade de arguments e casos mais comuns.

function f(x, y=12) {
  // y vale 12 se não for passado (ou passado como undefined)
  return x + y;
}
f(3) == 15
function f(x, ...y) {
  // y é um Array
  return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
  return x + y + z;
}
// Passa cada emelento do array como um argumento
f(...[1,2,3]) == 6

Let + Const

Blocos com escopo vinculado. let é o novo var. const é definido uam vez apenas. Restrições estáticas previnem o uso antes da declaração.

function f() {
  {
    let x;
    {
      // funciona, nome com escopo definido no bloco
      const x = "sneaky";
      // error, const
      x = "foo";
    }
    // erro, já definido no bloco
    let x = "inner";
  }
}

Iterators + For..Of

Objetos Iteratores permitem iterações como CLR IEnumerable ou Java Iteratable. Generalizar o for..in para uma iteração customizada com for..of. Não é necessário executar em um array, permitindo padrões mais flexíveis, como LINQ.

let fibonacci = {
  [Symbol.iterator]() {
    let pre = 0, cur = 1;
    return {
      next() {
        [pre, cur] = [cur, pre + cur];
        return { done: false, value: cur }
      }
    }
  }
}

for (var n of fibonacci) {
  // truncate the sequence at 1000
  // para a sequencia em 1000
  if (n > 1000)
    break;
  print(n);
}

A sintaxe de Iteration é baseada nas interfaces (usando sintaxe doTypeScript para demonstração apenas):

interface IteratorResult {
  done: boolean;
  value: any;
}
interface Iterator {
  next(): IteratorResult;
}
interface Iterable {
  [Symbol.iterator](): Iterator
}

Generators

Generators simplificam a criação de iterações usando function* e yield. Uma função declarada como function* retorna uma instância de um Generator. Generators são subtipos de iterators que incluem métodos adicionais, next e throw. Eles permitem que valores sejam retornados ao generator, então yield é uma forma de expressão que retorna um valor.

Nota: Também pode ser usados para permitir 'esperar' como em programação assíncrona, veja também a proposta do ES7, await.

var fibonacci = {
  [Symbol.iterator]: function*() {
    var pre = 0, cur = 1;
    for (;;) {
      var temp = pre;
      pre = cur;
      cur += temp;
      yield cur;
    }
  }
}

for (var n of fibonacci) {
  // truncate the sequence at 1000
  if (n > 1000)
    break;
  print(n);
}

A interface do generator é (usando a sintaxe do TypeScript para demonstração apenas):

interface Generator extends Iterator {
    next(value?: any): IteratorResult;
    throw(exception: any);
}

Comprehensions

Comprehensions de arrays e generator fornecem um processamento declarativo simples, semelhante ao usado em muitos padrões de programação funcional.

// Array comprehensions
var results = [
  for(c of customers)
    if (c.city == "Seattle")
      { name: c.name, age: c.age }
]

// Generator comprehensions
var results = (
  for(c of customers)
    if (c.city == "Seattle")
      { name: c.name, age: c.age }
)

Unicode

Adições retroativas para suporte completo a Unicode, incluindo a nova forma literal do unicode em strings e o novo modo do RegExp u, para lidar com pontos no código, assim como novas APIs para processar strings em códigos 21bit. Essas adições auxiliam a contrução de apps globais em Javascript.

// o mesmo que no ES5.1
"𠮷".length == 2

// novo comportamento RegExp, opcionalopt-in ‘u’
"𠮷".match(/./u)[0].length == 2

// nova sintaxe
"\u{20BB7}"=="𠮷"=="\uD842\uDFB7"

// nova opção para string
"𠮷".codePointAt(0) == 0x20BB7

// for-of itera em pontos de código
for(var c of "𠮷") {
  console.log(c);
}

Modules

Suporte nativo para módulos e definição de componentes. Códifica padrões de carregamento de módulo populares (AMD, CommonJS). Comportamento de carregamento em tempo de execução definido por um padrão no host. Modelos implícitos assíncronos , nenhum código é executado até que os módulos requisitados estejam disponíveis e processados.

// lib/math.js
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;
// app.js
module math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));

Algumas funcionalidades adicionais incluem export default e export *:

// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
    return Math.exp(x);
}
// app.js
module math from "lib/mathplusplus";
import exp from "lib/mathplusplus";
alert("2π = " + exp(math.pi, math.e));

Module Loaders

Module loaders suportam:

  • carregamento dinâmico
  • isolamento de estado
  • isolamento de namespace global
  • hooks de compilação
  • virtualização aninhada

O module loader padrão pode ser configurado e novos loaders podem ser contruídos para avaliar e carregar código em contexto isolado ou restrito

// Carregamento dinamico – ‘System’ é o loader padrão
System.import('lib/math').then(function(m) {
  alert("2π = " + m.sum(m.pi, m.pi));
});

// Cria sandboxes de execução – novos Loaders
var loader = new Loader({
  global: fixup(window) // replace ‘console.log’
});
loader.eval("console.log('hello world!');");

// Manipulação do módulo cache
System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized
System.set('jquery', Module({$: $})); // WARNING: não finalizado ainda

Map + Set + WeakMap + WeakSet

Estruturas de dados eficientes para algorítimos comuns. WeakMaps fornecem um mapa seguro de

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set

Proxies

Proxies permitem a criação de objetos com todos os comportamentos disponíveis no objeto que o contém, Podem ser usados para interceptação, virtualização de objetos, logs, profiles, etc.

// Proxying a normal object
// Proxy em um objeto normal
var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}!`;
  }
};��

var p = new Proxy(target, handler);
p.world === 'Hello, world!';
// Proxy em  um objeto função
var target = function () { return 'I am the target'; };
var handler = {
  apply: function (receiver, ...args) {
    return 'I am the proxy';
  }
};��

var p = new Proxy(target, handler);
p() === 'I am the proxy';

Existem métodos disponíveis para todas as meta-operações em tempo de execução:

var handler =
{
  get:...,
  set:...,
  has:...,
  deleteProperty:...,
  apply:...,
  construct:...,
  getOwnPropertyDescriptor:...,
  defineProperty:...,
  getPrototypeOf:...,
  setPrototypeOf:...,
  enumerate:...,
  ownKeys:...,
  preventExtensions:...,
  isExtensible:...
}

Symbols

Symbols permitem controle sobre o estado do objeto. Symbols permitem que propriedades sejam indexadas tanto por string (como no ES5) como symbol. Symbols são um novo tipo primitivo. Parâmetro opcional, name , usado em debug, mas não é parte da identidade. Symbols são únicos (como gensym), mas não são privados já que são expostos em funcionalidades comoObject.getOwnPropertySymbols.

(function() {

  // symbol no escopo do módulo
  var key = Symbol("key");

  function MyClass(privateData) {
    this[key] = privateData;
  }

  MyClass.prototype = {
    doStuff: function() {
      ... this[key] ...
    }
  };

})();

var c = new MyClass("hello")
c["key"] === undefined

Subclassable Built-ins

No ES6, objetos nativos como Array, Date e DOM Elements podem ter subclasses.

Contrução de objetos para uma função chamada Ctor agora levam duas etapas (ambas disparadas virtualmente):

  • Chame Ctor[@@create] para alocar o objeto, instalando qualquer comportamento especial
  • Chame o construtor ou uma nova instância para inicializar

O simbolo @@create estádisponível través de Symbol.create. Objetos nativos agora expôem seus métodos @@create explicitamente..

// Pseudo-código de Array
class Array {
    constructor(...args) { /* ... */ }
    static [Symbol.create]() {
        // Install special [[DefineOwnProperty]]
        // to magically update 'length'
    }
}

// User code of Array subclass
class MyArray extends Array {
    constructor(...args) { super(...args); }
}

// 'new' em duas fases:
// 1) Chame @@create para alocar o obejto
// 2) Chame o construtctor na nova instancia
var arr = new MyArray();
arr[1] = 12;
arr.length == 2

Math + Number + String + Object APIs

Muitas novas adições, incluindo novas libraries de matemática, conversão de Arrays e Object.assign para cópias.

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".contains("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // retorna um Array verdadeiro
Array.of(1, 2, 3) // Semelhante a new Array(...), mas sem comportamento especial de um argumento
[0, 0, 0].fill(7, 1) // [0,7,7]
[1,2,3].findIndex(x => x == 2) // 1
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })

Binary and Octal Literals

Duas novas formas de numeros literais foram adicionadas, para binários (b) e octais (o).

0b111110111 === 503 // true
0o767 === 503 // true

Promises

Promises são uma library para programação assíncrona. Promises são representações de primeira classe de um valor que pode estar disponível no futuro. Promises são usadas em muitas libraries javascript que já existem.

function timeout(duration = 0) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, duration);
    })
}

var p = timeout(1000).then(() => {
    return timeout(2000);
}).then(() => {
    throw new Error("hmm");
}).catch(err => {
    return Promise.all([timeout(100), timeout(200)]);
})

Reflect API

A Reflection API expõe as meta-operações em objetos em tempo de execução. De fato isto é o inverso da Proxy API, e permite fazer chamadas correspondentes as mesmas meta-operações que os métodos de proxy. Muito úteis pata implementação de proxies.

// Sem exemplo

Tail Calls

Chamadas no final são garantidas para não aumentar a fila ilimitadamente. Fazem algorítimos recursivos mais seguros para dados inesperados.

function factorial(n, acc = 1) {
    'use strict';
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc);
}

// Estouro de memória na maioria das implentações de hoje,
// mas seguro em entradas de dados aleatória no ES6
factorial(100000)

About

Visão geral das novas funcionalidades do ECMAScript 6

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published