Baixe o app para aproveitar ainda mais
Prévia do material em texto
Começando com ES6 Jul 30, 2015 • 3052 words • 16 minutes read #JAVASCRIPT H O M E A R T I C L E S A B O U T Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Bem, nas ultimas semanas me deparei com alguns tutoriais utilizando ES6 (tambem conhecido como ECMAScript 2015 ou Harmony) como exemplo. Sim achei algumas coisas divinas, já outras são coisas que temos no Node.js por exemplo. Outras são Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD coisas que alguns queriam a muito tempo para aproximar desenvolvedores back- end da linguagem JavaScript como classes. Pois bem, este pode ser um post inútil para alguns, mas foi o que absorvi no ultimo mês e estou começando a utilizar em projetos pessoais com Browserify e Babelify. Na ultima semana terminei de assistir a um workshop realizado pelo @fnando mostrando alguns goodies de JS já utilizando ES6. Confesso que �quei perplexo no início já que o compilador �cava cuspindo um monte de código sem sentido ES5, porem tudo funcionando. Então percebi assim duas coisas: 1- ES6 não é difícil se você já sabe JS; 2- Babel é o transpiler mais quente do momento (Sorry TypeScript). Pois bem, agora chegou a hora de passar o pouco que aprendi adiante, não se preocupe se você é um back-end developer, eu acredito que este pode ser o melhor momento para você aprender ES6, já que ele é muito mais clean e possui uma sintaxe um pouco mais bonita (Sugar syntax). GOALS Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Modules; Arrow Functions; Classes; let & const; Template strings. Modules Porque não utilizar módulos hoje? Nós já fazemos isso no Node utilizando o padrão CommonJS ou até mesmo no front-end utilizando Browserify e RequireJS. //sum.js var sum = function(x, y) { return x + y; }; export { sum } //multiplier.js var multiplier = function(x, y) { return x * y; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Nada de mais certo? Já temos isso no Node, declaramos algo a ser exportado com module.exports e utilizamos require para utilizarmos em nossa app. Ok, tudo muito legal…era isso que queriamos…um belo dia nativo para os browsers. Mas calma, ainda é possível brincar um pouco mais: }; export { multiplier } //calculator.js import { sum } from "./sum"; import { multiplier } from "./multiplier"; var result = sum(15,27); // 42 result = multiplier(6,7); // 42 //calculator.js export function sum(x, y) { return x + y; }; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD export function multiplier(x, y) { return x * y; }; // --- OU --- var sum = function (x, y) { return x + y; }, multiplier = function (x, y) { return x * y; }; export { sum, multiplier }; //app.js import { sum, multiplier } from 'calculator'; // Importar ambas as declarações de um mesmo arquivo // --- OU --- import { sum as somar, multiplier as multiplicar } from 'calculator'; // Utilizar alias para as declarações exportadas // --- OU --- import * from 'calculator'; // Importar todas as declarações exportadas Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD São algumas outras opções do que se pode fazer com módulos no ES6. Acredito que para alguns isso não será grande coisa, mas achei interessante ter isso nativo no lado cliente. Arrow Functions Bom, muita gente que eu vi falar de ES6, estavam completamente apaixonados pela arrow functions, e não é pra menos, já que além de diminuir a quantidade de código também te da “de graça” o escopo pai, sem precisar de .bind(this) nem nada do tipo. Vamos a um exemplo utilizando coisas que já fazemos no JavaScript. var products = [ { name: 'Macbook Pro', val: 1999 }, { name: 'Go Pro', val: 299 }, { name: 'PlayStation 4', val: 599 } ]; console.log(products.map(prod => prod.val)); Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Bem simples este exemplo utilizando .map certo? Não sei mais o que podemos utilizar de exemplo, vamos com as funções simplistas utilizadas acima: // [1999, 299, 599] // [1999, 299, 599] var prices = products.map(prod => prod.val); var sum = prices.reduce((a, b) => a + b); // 2897 console.log(sum); var productsWithTax = products.map(prod => { var val = prod.val; return val * 1.6; }); console.log(productsWithTax); // Nossos produtos com 60% de imposto // Sem levar em consideração a conversão para o dolar =) var sum = (x, y) => { return x + y; }, Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Entendeu como funciona? Ainda assim temos passagem por block scope com nenhum ou mais argumentos, ou simplesmente a expressão sem necessidade de um bloco. Algo assim: multiplier = (x, y) => { return x * y; }; () => { … } // Sem argumentos x => { … } // Um argumento (x, y) => { … } // N argumentos x => { return x * x } // Block scope x => x * x // Mesma expressão sem necessidade do block scope Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Sabe Promise? Eu venho utilizando esta abordagem em meus projetos e estou bem satisfeito. Vamos a um exemplo simples: Existem N partes que você pode utilizar Arrow Functions, basta ver se faz sentido e, utilizar em seu projeto. var promise = new Promise((resolve, reject) => { if (/* Condição */) { resolve("Promise + Arrow Functions = <3"); } else { reject(Error("Oops!")); } }); promise.then((result) => { console.log(result); // "Promise + Arrow Functions = <3" }, (err) => { console.log(err); // Error: "Oops!" }); Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Classes Agora vem a parte legal, eu particularmente conheço muita gente que fala que JavaScript não suporta Orientação a Objetos, que isso, que aquilo. Certa vez, lendo o livro Secrets of the JavaScript Ninja do @jeresig, ele cita algumas vezes no começo sobre funções serem objetos de primeira classe e uma parte sobre funções construtoras. Depois que li isso tive certeza quanto ao JavaScript supoartar OO mesmo sendo baseada no que é chamado de prototype . Você pode nunca ter visto a palavra class , mas provavelmente já viu algo do tipo: function Todo () { var items = []; this.getItems = function () { return items; }; this.addItem = function(item) { items.push(item); }; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Bem, mesmo não aceitando você acabou de ver um pseudo código bem simples de como objetos funcionam no JS. Não vou prolongar este post explicando sobre isso, você pode entender o conceito neste ótimo post do @wbrunom. Sem mais delongas… vamos nos beni�ciar das classes do ES6 utilizando exatamente o mesmo código acima: } var todo = new Todo(); todo.addItem('Aprender ES6'); todo.addItem('Ir no BrazilJS'); console.log(todo.getItems()); // ["Aprender ES6", "Ir no BrazilJS"] class Todo { constructor() { this.items = []; } getItems () { return this.items; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Pronto! Ta ai seu class . Vamos analisar o código: De�nimos no constructor que iremos criar uma propriedade items que nesse caso não esta recebendo nenhum argumento; Diferente da função construtora, a propriedade items não é privada; De�nimos os mesmos métodos utilizandoname () { ... } , o que funciona exatamente da mesma forma; Instanciamos o objeto exatamente da mesma forma que a função construtora. Eu venho acompanhando o blog do Dr. Axel Rauschmayer que esta atualmente escrevendo o livro Exploring ES6 e achei algumas referencias para deixar um } addItem(item) { this.items.push(item); } } var todo = new Todo(); todo.addItem('Aprender ES6'); todo.addItem('Ir no BrazilJS'); console.log(todo.getItems()); // ["Aprender ES6", "Ir no BrazilJS"] Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD atributo privado em uma classe. Não é muito elegante, mas funciona: Como disse, não é uma maneira muito elegante, mas se for necessário você provavelmente vai separa isso num módulo e vai exportar apenas a classe. var _items = []; class Todo { constructor() { } getItems () { return _items; } addItem(item) { _items.push(item); } } Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Também podemos ter o conceito de herança muito mais claro com ES6, vou utilizar um exempo ridiculo que vi na faculdade mas acho que serve nesse caso: class Conta { constructor(number, dono) { this.number = number; this.owner = dono; this.saldo = 0; } deposit(qnt) { if(qnt > 0) { return this.saldo += qnt; } throw new Error("Insira um valor valido"); } withdraw(qnt) { if(qnt <= this.saldo) { return this.saldo -= qnt; } throw new Error("Você não tem saldo suficiente"); } checkSaldo() { return this.saldo; } Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Criamos a ContaCorrente ContaCorrente e utilizamos extends que herda os métodos da classe pai; Perceba que no construtor, utilizamos a mesma assinatura, porem passamos como atributos para o método super que nada mais é do que o construtor da classe pai. Esse conceito de herança já existe a algum tempo, mas o código serial algo assim: } class ContaCorrente extends Conta { constructor(number, dono){ super(number, dono); this.type = 'Corrente'; } } var cc = new ContaCorrente(10007,'Rafaell'); cc.deposit(1000); console.log(cc.checkSaldo()); // 1000 Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Funciona, mas realmente é algo um pouco mais cansativo para se ler e/ou escrever. let & const Uma coisa interessante que veio com ES6 mas me deixou confuso no inicio foi let e o block scope. O let funciona parecido como o var porem ele corrige o problema que temos quanto ao escopo e hoisting, ou seja, ela ira apenas existir quando de�nida em um bloco ( {} ) onde sera criado seu escopo. function Conta (number, dono) { // Code }; function ContaCorrente (number, dono) { // Code }; ContaCorrente.prototype = Object.create(Conta.prototype); ContaCorrente.prototype.constructor = ContaCorrente; ContaCorrente.parent = Conta.prototype; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Nesse caso utilizando let , podemos ver claramente que o valor de b não é declarado fora do bloco if na etapa de hoisting. Ao meu ver isso é até complicado de se explicar, mas vou utilizar um outro exemplo que talvez fara mais sentido: // ES5 var a = 1; if (1 === a) { var b = 2; } console.log(b); // 2 // ES6 var a = 1; if (1 === a) { let b = 2; } console.log(b); // Uncaught ReferenceError: b is not defined Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Acho que agora vou conseguir explicar melhor. Se você não sabia, quando utiliza o for , a variavel que usa como count é de�nida globalmente no escopo durante o hoisting, enquanto a variável a esta presente apenas dentro da função someFunc . A função cria um novo contexto para a variável a , porem ela também pode enxergar a variável i do nosso loop. Uma forma de evitarmos isso durante o hoisting é utilizando let , que cria uma variável dentro de um escopo isolado de�nido por blocos ( {} ): for (var i = 0; i < 3; i++) { // … } function someFunc() { var a = 'My Secret Value'; } console.log(i); // 3 console.log(a); // Uncaught ReferenceError: a is not defined Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Meh…constantes Agora temos const funciona também respeitando o block scoping como let , porem se comporta da forma que uma constante deveria se comportar (ready only). for (let i = 0; i < 3; i++) { // … } function someFunc() { let a = 'My Secret Value'; } console.log(i); // Uncaught ReferenceError: i is not defined console.log(a); // Uncaught ReferenceError: a is not defined const PI = 3.141593; PI = 3.14; // throws “PI” is read-only Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Template strings Depois de muito tempo, agora temos template strings nativo com ES6. WAT?! Melhor eu mostrar =) // Sem template String let link = 'http://www.ecma-international.org/ecma-262/6.0/'; let cssClass = 'link-js'; let text = 'ECMAScript® 2015 Language Specification'; let elementTpl = '<a href="' + link + '" class="' + cssClass + '">' + text + '< console.log(elementTpl); // <a href="http://..." class="link-js">ECMAScript® 2015...</a> // Com template String elementTpl = `<a href="${link}" class="${cssClass}">${text}</a>`; Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD Não é lindo? Simples? Quase uma obra divina? E o melhor, apenas utilizando ` Conclusão ES6 não é pra ser usado no futuro, etc… é pra ser aprendido e se possível utilizado hoje! Você pode aprender lendo sobre isso em blogs ou vendo vídeos como eu �z, ou procurar alguma documentação. Algumas boas referencias para estudo e opções de transpilers: ES6-Learning by @ericdouglas_ console.log(elementTpl); // <a href="http://..." class="link-js">ECMAScript® 2015...</a> Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD S H A R E R E F E R E N C E S → Learn ES2015 (Babel Website) → ES6 Rocks → ECMAScript 6 Tutorial ECMAScript 6 Tools by addyosmani Como fazer isso? Bom, eu li num post do @jaydson sobre utilizar o Babel como transpiler e carregar os módulos com o Browserify. Isso tem funcionado bem nos meus projetos, ainda não consegui colocar isso aqui no Tripda, mas não vai demorar muito. =) Create PDF in your applications with the Pdfcrowd HTML to PDF API PDFCROWD
Compartilhar