├── 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 | --------------------------------------------------------------------------------