├── License.md
└── README.md
/License.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Luke Hoban
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ECMAScript 6
2 |
3 | ## Introdução
4 | ECMAScript 6, também conhecido como ECMAScript 2015, é a última versão do padrão ECMAScript. ES6 é
5 | uma atualização significativa para a linguagem e é a primeira atualização desde que ES5 se tornou um
6 | padrão em 2009. A implementação dessas funcionalidades nas principais engines de JavaScript
7 | [já está em andamento](http://kangax.github.io/es5-compat-table/es6/).
8 |
9 | Veja o [padrão ES6](http://www.ecma-international.org/ecma-262/6.0/) para a especificação completa
10 | da linguagem ECMAScript 6.
11 |
12 | ES6 inclui as seguintes novas funcionalidades:
13 | - [Setas (Arrows)](#arrows)
14 | - [Classes](#classes)
15 | - [Objetos Literais Aprimorados (Enhanced Object Literals)](#enhanced-object-literals)
16 | - [Template Strings](#template-strings)
17 | - [Destructuring](#destructuring)
18 | - [Default + Rest + Spread](#default--rest--spread)
19 | - [let + const](#let--const)
20 | - [Iterators + for..of](#iterators--forof)
21 | - [Geradores (Generators)](#generators)
22 | - [Unicode](#unicode)
23 | - [Módulos (Modules)](#modules)
24 | - [Carregadores de Módulos (Module Loaders)](#module-loaders)
25 | - [Map + Set + WeakMap + WeakSet](#map--set--weakmap--weakset)
26 | - [Proxies](#proxies)
27 | - [Symbols](#symbols)
28 | - [Subclassable Built-ins](#subclassable-built-ins)
29 | - [Math + Number + String + Array + APIs de Objetos](#math--number--string--array--object-apis)
30 | - [Binário e Octal literais](#binary-and-octal-literals)
31 | - [Promises](#promises)
32 | - [Reflect API](#reflect-api)
33 | - [Tail Calls](#tail-calls)
34 |
35 | ## Funcionalidades ECMAScript
36 |
37 | ### Setas (Arrows)
38 | Setas são a maneira simplificada para funções usando a sintaxe `=>`. Elas são sintaticamente
39 | similares ao recurso relacionado em C#, Java 8 e CofeeScript. Suportam tanto corpos de blocos
40 | statement, quanto os de expressões que retornam o valor da expressão. Diferentemente de funções,
41 | Setas compartilham o mesmo léxico `this`, tanto como o código que o envolve (surrounding code).
42 |
43 | ```JavaScript
44 | // Expressão
45 | var odds = evens.map(v => v + 1);
46 | var nums = evens.map((v, i) => v + i);
47 | var pairs = evens.map(v => ({even: v, odd: v + 1}));
48 |
49 | // Statement
50 | nums.forEach(v => {
51 | if (v % 5 === 0)
52 | fives.push(v);
53 | });
54 |
55 | // Léxico "this"
56 | var bob = {
57 | _name: "Bob",
58 | _friends: [],
59 | printFriends() {
60 | this._friends.forEach(f =>
61 | console.log(this._name + " knows " + f));
62 | }
63 | }
64 | ```
65 |
66 | ### Classes
67 | Classes ES6 são simplesmente um "docinho" para o padrão OO baseado em protótipos. Ter uma forma
68 | declarativa, conveniente e simples de padrões de classes faz delas mais fáceis de serem usadas e
69 | encoraja a interoperabilidade. Classes suportam herança baseada em protótipos, chamadas super,
70 | métodos instanciados e estáticos e construtores.
71 |
72 | ```JavaScript
73 | class SkinnedMesh extends THREE.Mesh {
74 | constructor(geometry, materials) {
75 | super(geometry, materials);
76 |
77 | this.idMatrix = SkinnedMesh.defaultMatrix();
78 | this.bones = [];
79 | this.boneMatrices = [];
80 | //...
81 | }
82 | update(camera) {
83 | //...
84 | super.update();
85 | }
86 | get boneCount() {
87 | return this.bones.length;
88 | }
89 | set matrixType(matrixType) {
90 | this.idMatrix = SkinnedMesh[matrixType]();
91 | }
92 | static defaultMatrix() {
93 | return new THREE.Matrix4();
94 | }
95 | }
96 | ```
97 |
98 | ### Objetos Literais Aprimorados (Enhanced Object Literals)
99 | Object Literals são estendidos para dar suporte à especificação de prototype na construção,
100 | simplificações para atribuições `foo: foo`, definição de métodos, chamadas super e computar propriedades
101 | de nome com expressões. Juntos, estes fazem Objetos Literais e declarações de classes mais próximos e
102 | o benefício do design baseado em objetos com as mesmas conveniências.
103 |
104 | ```JavaScript
105 | var obj = {
106 | // __proto__
107 | __proto__: theProtoObj,
108 | // Simplificação para ‘handler: handler’
109 | handler,
110 | // Métodos
111 | toString() {
112 | // Chamadas super
113 | return "d " + super.toString();
114 | },
115 | // Nomes de propriedades computados (dinamicos)
116 | [ 'prop_' + (() => 42)() ]: 42
117 | };
118 | ```
119 |
120 | ### Template Strings
121 | Template Strings proveem "açúcar sintático" para montar strings. São similares a interpolação de
122 | strings em Perl, Python e outros. Opcionalmente, uma tag pode ser adicionada para permitir a
123 | construção da string ser customizada, evitando ataques de injeção ou construindo estruturas de dados
124 | de alto nível a partir de conteúdos de strings.
125 |
126 | ```JavaScript
127 | // Criação básica de string literal
128 | `In JavaScript '\n' is a line-feed.`
129 |
130 | // Strings multilinhas
131 | `In JavaScript this is
132 | not legal.`
133 |
134 | // Interpolation de string
135 | var name = "Bob", time = "today";
136 | `Hello ${name}, how are you ${time}?`
137 |
138 | // Montar um prefixo de requisição HTTP pode ser usado para interpretar substutuições e construção
139 | POST`http://foo.org/bar?a=${a}&b=${b}
140 | Content-Type: application/json
141 | X-Credentials: ${credentials}
142 | { "foo": ${foo},
143 | "bar": ${bar}}`(myOnReadyStateChangeHandler);
144 | ```
145 |
146 | ### Destructuring
147 | Desestruturação permite binding usando matching de padrões com suporte para matching de arrays e
148 | objetos. Desestruturação é "fail-soft", similar ao lookup padrão de objeto `foo["bar"]`, produzindo
149 | valores `undefined` quando não encontrado.
150 |
151 | ```JavaScript
152 | // Matching de array
153 | var [a, , b] = [1,2,3];
154 |
155 | // Matching de objeto
156 | var { op: a, lhs: { op: b }, rhs: c }
157 | = getASTNode()
158 |
159 | // shorthand para matching de objeto faz
160 | // bind para `op`, `lhs` e `rhs` no escopo
161 | var {op, lhs, rhs} = getASTNode()
162 |
163 | // Pode ser usado na posição do parametro
164 | function g({name: x}) {
165 | console.log(x);
166 | }
167 | g({name: 5})
168 |
169 | // Desestruturação fail-soft
170 | var [a] = [];
171 | a === undefined;
172 |
173 | // Desestruturação fail-soft com defaults
174 | var [a = 1] = [];
175 | a === 1;
176 | ```
177 |
178 | ### Default + Rest + Spread
179 | Valores padrão de parâmetros avaliados pelo "chamador". Transforma um array em argumentos
180 | consecutivos em uma chamada de função. Vincula (bind) parâmetros para array. Rest troca
181 | a necessidade de argumentos e endereça casos de espaços comuns mais diretamente.
182 |
183 | ```JavaScript
184 | function f(x, y=12) {
185 | // y é 12 se não for passado (ou passado como undefined)
186 | return x + y;
187 | }
188 | f(3) == 15
189 | ```
190 | ```JavaScript
191 | function f(x, ...y) {
192 | // y é um Array
193 | return x * y.length;
194 | }
195 | f(3, "hello", true) == 6
196 | ```
197 | ```JavaScript
198 | function f(x, y, z) {
199 | return x + y + z;
200 | }
201 | // Passa cada elementos do array como argumento
202 | f(...[1,2,3]) == 6
203 | ```
204 |
205 | ### let + const
206 | `let` é o novo `var`. `const` é de atribuição única (single-assignment). Restrições de Estático
207 | previnem o uso antes da atribuição.
208 |
209 | ```JavaScript
210 | function f() {
211 | {
212 | let x;
213 | {
214 | // OK, escopo de bloco
215 | const x = "sneaky";
216 | // error, const
217 | x = "foo";
218 | }
219 | // error: já declarado no bloco
220 | let x = "inner";
221 | }
222 | }
223 | ```
224 |
225 | ### Iterators + For..Of
226 | Objetos iteradores permitem iteradores personalizações como CLR IEnumerable ou Java Iterable.
227 | Generalização de `for..in` para iteração customizada com `for..of`. Não é preciso array, o que
228 | permite padrões lazy de design como LINQ.
229 |
230 | ```JavaScript
231 | let fibonacci = {
232 | [Symbol.iterator]() {
233 | let pre = 0, cur = 1;
234 | return {
235 | next() {
236 | [pre, cur] = [cur, pre + cur];
237 | return { done: false, value: cur }
238 | }
239 | }
240 | }
241 | }
242 |
243 | for (var n of fibonacci) {
244 | // trunca a sequência em 1000
245 | if (n > 1000)
246 | break;
247 | console.log(n);
248 | }
249 | ```
250 |
251 | A iteração é baseada nessas interfaces (usando a sintaxe de tipo de
252 | [TypeScript](http://typescriptlang.org) somente para exemplificar):
253 | ```TypeScript
254 | interface IteratorResult {
255 | done: boolean;
256 | value: any;
257 | }
258 | interface Iterator {
259 | next(): IteratorResult;
260 | }
261 | interface Iterable {
262 | [Symbol.iterator](): Iterator
263 | }
264 | ```
265 |
266 | ### Geradores (Generators)
267 | Generators simplificam iterações usando `function*` and `yield`. Uma função declarada como
268 | `function*` retorna uma instância de Generator. Generators são subtipos de iteradores que incluem
269 | `next` e `throw`. Estes valores permitem voltar no gerador, então `yield` é uma forma de expressão
270 | que retorna um valor -- ou o lança (throws).
271 |
272 | Nota: Também pode ser usado para habilitar programação assíncrona "‘await’-like", tal como a
273 | proposta de `await` em ES7.
274 |
275 | ```JavaScript
276 | var fibonacci = {
277 | [Symbol.iterator]: function*() {
278 | var pre = 0, cur = 1;
279 | for (;;) {
280 | var temp = pre;
281 | pre = cur;
282 | cur += temp;
283 | yield cur;
284 | }
285 | }
286 | }
287 |
288 | for (var n of fibonacci) {
289 | // truncate the sequence at 1000
290 | if (n > 1000)
291 | break;
292 | console.log(n);
293 | }
294 | ```
295 |
296 | A iteração é baseada nessas interfaces (usando a sintaxe de tipo de
297 | [TypeScript](http://typescriptlang.org) somente para exemplificar):
298 |
299 | ```TypeScript
300 | interface Generator extends Iterator {
301 | next(value?: any): IteratorResult;
302 | throw(exception: any);
303 | }
304 | ```
305 |
306 | ### Unicode
307 | Foram feitas adições para suporte total a Unicode, incluindo a nova forma literal de Unicode em
308 | string e o novo modo de expressões regulares `u` para lidar com code points, tal como novas APIs
309 | para processar strings no nível em código 21bit. Essas adições permitem o desenvolvimento de
310 | aplicativos globais em JavaScript.
311 |
312 | ```JavaScript
313 | // mesmo que em ES5.1
314 | "𠮷".length == 2
315 |
316 | // novo ‘u’ de expressões regulares
317 | "𠮷".match(/./u)[0].length == 2
318 |
319 | // nova maneira
320 | "\u{20BB7}"=="𠮷"=="\uD842\uDFB7"
321 |
322 | // novo String ops
323 | "𠮷".codePointAt(0) == 0x20BB7
324 |
325 | // for-of itera pontos de código (code points)
326 | for(var c of "𠮷") {
327 | console.log(c);
328 | }
329 | ```
330 |
331 | ### Módulos (Modules)
332 | Suporte a Módulos em nível de linguagem para definição de componentes. Codifica padrões de loaders
333 | de módulos populares em JavaScript (AMD, CommonJS). Comportamente em runtime definido por um loader
334 | que pode ser definido. Modelo assíncrono implícito -- nenhum código executa até os módulos
335 | requeridos ficarem disponíveis e processados.
336 |
337 | ```JavaScript
338 | // lib/math.js
339 | export function sum(x, y) {
340 | return x + y;
341 | }
342 | export var pi = 3.141593;
343 | ```
344 | ```JavaScript
345 | // app.js
346 | import * as math from "lib/math";
347 | alert("2π = " + math.sum(math.pi, math.pi));
348 | ```
349 | ```JavaScript
350 | // otherApp.js
351 | import {sum, pi} from "lib/math";
352 | alert("2π = " + sum(pi, pi));
353 | ```
354 |
355 | Algumas features adicionais incluem `export default` e `export *`:
356 |
357 | ```JavaScript
358 | // lib/mathplusplus.js
359 | export * from "lib/math";
360 | export var e = 2.71828182846;
361 | export default function(x) {
362 | return Math.log(x);
363 | }
364 | ```
365 | ```JavaScript
366 | // app.js
367 | import ln, {pi, e} from "lib/mathplusplus";
368 | alert("2π = " + ln(e)*pi*2);
369 | ```
370 |
371 | ### Carregadores de Módulos (Module Loaders)
372 | Module loaders suportam:
373 | - Carregamento Dinâmico (Dynamic loading)
374 | - Isolamento de Estado (State isolation)
375 | - Isolamento Global de Namespace (Global namespace isolation)
376 | - Hooks de Compilação (Compilation hooks)
377 | - Virtualização Aninhada (Nested virtualization)
378 |
379 | O loader padrão de módulo pode ser configurado e novos loaders podem ser construídos para processar
380 | e carregar códigos em contextos isolados ou restringidos.
381 |
382 | ```JavaScript
383 | // Carregamento Dinâmico -- ‘System’ é o loader padrão
384 | System.import('lib/math').then(function(m) {
385 | alert("2π = " + m.sum(m.pi, m.pi));
386 | });
387 |
388 | // Cria sandbox de execução
389 | var loader = new Loader({
390 | global: fixup(window) // substitui ‘console.log’
391 | });
392 | loader.eval("console.log('hello world!');");
393 |
394 | // Manipula módulo de cache diretamente
395 | System.get('jquery');
396 | System.set('jquery', Module({$: $})); // CUIDADO: ainda não finalizado
397 | ```
398 |
399 | ### Map + Set + WeakMap + WeakSet
400 | Estruturas de dados eficientes para algoritmos comuns. WeakMaps proveem coleções de pares
401 | chave/valor em que as chaves são fracamente referenciadas (weakly referenced).
402 |
403 | ```JavaScript
404 | // Sets
405 | var s = new Set();
406 | s.add("hello").add("goodbye").add("hello");
407 | s.size === 2;
408 | s.has("hello") === true;
409 |
410 | // Maps
411 | var m = new Map();
412 | m.set("hello", 42);
413 | m.set(s, 34);
414 | m.get(s) == 34;
415 |
416 | // Weak Maps
417 | var wm = new WeakMap();
418 | wm.set(s, { extra: 42 });
419 | wm.size === undefined
420 |
421 | // Weak Sets
422 | var ws = new WeakSet();
423 | ws.add({ data: 42 });
424 | // Porque o objeto adicionado não possui outras referências, não será mantido no conjunto
425 | ```
426 |
427 | ### Proxies
428 | Proxies permitem a criação de objetos com a gama completa de comportamentos de host objects de
429 | JavaScript. Podem ser usados para interceptação, virtualização de objetos, logging/profiling etc.
430 |
431 | ```JavaScript
432 | // Proxying de um objeto normal
433 | var target = {};
434 | var handler = {
435 | get: function (receiver, name) {
436 | return `Hello, ${name}!`;
437 | }
438 | };
439 |
440 | var p = new Proxy(target, handler);
441 | p.world === 'Hello, world!';
442 | ```
443 |
444 | ```JavaScript
445 | // Proxying de um objeto de função
446 | var target = function () { return 'I am the target'; };
447 | var handler = {
448 | apply: function (receiver, ...args) {
449 | return 'I am the proxy';
450 | }
451 | };
452 |
453 | var p = new Proxy(target, handler);
454 | p() === 'I am the proxy';
455 | ```
456 |
457 | Existem "armadilhas" para todas as metaoperações a nível de runtime:
458 |
459 | ```JavaScript
460 | var handler =
461 | {
462 | get:...,
463 | set:...,
464 | has:...,
465 | deleteProperty:...,
466 | apply:...,
467 | construct:...,
468 | getOwnPropertyDescriptor:...,
469 | defineProperty:...,
470 | getPrototypeOf:...,
471 | setPrototypeOf:...,
472 | enumerate:...,
473 | ownKeys:...,
474 | preventExtensions:...,
475 | isExtensible:...
476 | }
477 | ```
478 |
479 | ### Symbols
480 | Symbols são um novo tipo de primitivo que permitem controle de acesso ao estado de objeto. Permitem
481 | que se use propriedades como chave tanto para `string` (como em ES5), quanto `symbol`. Opcionalmente,
482 | é possível usar o parâmetro `description` em debugging -- mas não é parte da identidade. Symbols são
483 | únicos (como gensym), mas não privados, já que podem ser expostos através de características de
484 | reflection, como `Object.getOwnPropertySymbols`.
485 |
486 | ```JavaScript
487 | var MyClass = (function() {
488 |
489 | // módulo de símbolo em escopo
490 | var key = Symbol("key");
491 |
492 | function MyClass(privateData) {
493 | this[key] = privateData;
494 | }
495 |
496 | MyClass.prototype = {
497 | doStuff: function() {
498 | ... this[key] ...
499 | }
500 | };
501 |
502 | return MyClass;
503 | })();
504 |
505 | var c = new MyClass("hello")
506 | c["key"] === undefined
507 | ```
508 |
509 | ### Subclassable Built-ins
510 | Em ES6, built-ins como `Array`, `Date` e `Element`s DOM podem ser "subclasseados".
511 |
512 | Construção de Objeto para a função chamada `Ctor` agora usa 2 fases -- ambas virtualmente
513 | "despachadas" (dispatched):
514 |
515 | - Chama `Ctor[@@create]` para alocar o objeto, instalando qualquer comportamento especial
516 | - Invoca o construtor na nova instância para inicializar
517 |
518 | O conhecido símbolo `@@create` é avaliado via `Symbol.create`. Built-ins agora expõem explicitamente
519 | seus `@@create`.
520 |
521 | ```JavaScript
522 | // Pseudocódigo de Array
523 | class Array {
524 | constructor(...args) { /* ... */ }
525 | static [Symbol.create]() {
526 | // Instala [[DefineOwnProperty]]
527 | // para magicamente atualizar 'length'
528 | }
529 | }
530 |
531 | // Código de usuário do Array subclasseado
532 | class MyArray extends Array {
533 | constructor(...args) { super(...args); }
534 | }
535 |
536 | // "new" em 2 fases:
537 | // 1) Chama @@create para alocar o objeto
538 | // 2) Invoca o construtor na nova instância
539 | var arr = new MyArray();
540 | arr[1] = 12;
541 | arr.length == 2
542 | ```
543 |
544 | ### Math + Number + String + Array + APIs de Objetos
545 | Muitas novas adições de bibliotecas, incluindo bibliotecas core d Math, helpers de conversão de
546 | Array, helpers de String e `Object.assign` para copiar.
547 |
548 | ```JavaScript
549 | Number.EPSILON
550 | Number.isInteger(Infinity) // false
551 | Number.isNaN("NaN") // false
552 |
553 | Math.acosh(3) // 1.762747174039086
554 | Math.hypot(3, 4) // 5
555 | Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
556 |
557 | "abcde".includes("cd") // true
558 | "abc".repeat(3) // "abcabcabc"
559 |
560 | Array.from(document.querySelectorAll('*')) // Returns a real Array
561 | Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
562 | [0, 0, 0].fill(7, 1) // [0,7,7]
563 | [1, 2, 3].find(x => x == 3) // 3
564 | [1, 2, 3].findIndex(x => x == 2) // 1
565 | [1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
566 | ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
567 | ["a", "b", "c"].keys() // iterator 0, 1, 2
568 | ["a", "b", "c"].values() // iterator "a", "b", "c"
569 |
570 | Object.assign(Point, { origin: new Point(0,0) })
571 | ```
572 |
573 | ### Binário e Octal literais
574 | 2 novas formas de literais numéricos foram adicionados para binário (`b`) e octal (`o`).
575 |
576 | ```JavaScript
577 | 0b111110111 === 503 // true
578 | 0o767 === 503 // true
579 | ```
580 |
581 | ### Promises
582 | Promises são a biblioteca para programação assíncrona. Promises são a primeira representação de
583 | classe para um valor que pode estar disponível no futuro.
584 |
585 | ```JavaScript
586 | function timeout(duration = 0) {
587 | return new Promise((resolve, reject) => {
588 | setTimeout(resolve, duration);
589 | })
590 | }
591 |
592 | var p = timeout(1000).then(() => {
593 | return timeout(2000);
594 | }).then(() => {
595 | throw new Error("hmm");
596 | }).catch(err => {
597 | return Promise.all([timeout(100), timeout(200)]);
598 | })
599 | ```
600 |
601 | ### Reflect API
602 | API completa para reflection expõe metaoperações em nível de runtime em objetos. Isso é efetivamente
603 | o inverso da Proxy API e permite realizar chamadas correspondendo às mesmas metaoperações, como as
604 | proxy traps. Especialmente útil para implementar proxies.
605 |
606 | ```JavaScript
607 | // Ainda sem exemplo
608 | ```
609 |
610 | ### Tail Calls
611 | Chamadas em tail-position (no final da instrução) garantem o não crescimento da stack de forma
612 | descontrolada. Fazer algoritmos recursivos de forma segura em face a inputs descontrolados.
613 |
614 | ```JavaScript
615 | function factorial(n, acc = 1) {
616 | 'use strict';
617 | if (n <= 1) return acc;
618 | return factorial(n - 1, n * acc);
619 | }
620 |
621 | // Stack overflow na maioria das implementações atuais,
622 | // mas seguro em inputs arbitrários em ES6
623 | factorial(100000)
624 | ``
625 |
--------------------------------------------------------------------------------