Buscar

Iniciando com JavaScript

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

Continue navegando