? O guia completo já está disponível na Amazon

let , const e bloquear o escopo let permite criar declarações que estão vinculadas a qualquer bloco, chamado bloqueio de escopo. Em vez de usar var , que fornece escopo da função, é recomendável usar variáveis de bloco escasso ( let ou const ) no ES6.
var a = 2 ;
{
let a = 3 ;
console . log ( a ) ; // 3
let a = 5 ; // TypeError: Identifier 'a' has already been declared
}
console . log ( a ) ; // 2 Outra forma de declaração escolar em bloco é a const , que cria constantes. No ES6, um const representa uma referência constante a um valor. Em outras palavras, o conteúdo de Object e Array pode mudar, apenas a reinicialização da variável é impedida. Aqui está um exemplo simples:
{
const b = 5 ;
b = 10 ; // TypeError: Assignment to constant variable
const arr = [ 5 , 6 ] ;
arr . push ( 7 ) ;
console . log ( arr ) ; // [5,6,7]
arr = 10 ; // TypeError: Assignment to constant variable
arr [ 0 ] = 3 ; // value is mutable
console . log ( arr ) ; // [3,6,7]
}Algumas coisas a ter em mente:
let e const variam da elevação tradicional de variáveis e funções. let e const estão içados, mas não podem ser acessados antes de sua declaração, por causa da zona morta temporallet e const estão escopo para o bloco anexante mais próximo.const PI = 3.14 )const deve ser definido com sua declaração.const Over Over let , a menos que você planeje re-atribuir a variável. As funções de seta são uma notação curta para escrever funções no ES6. A definição da função de seta consiste em uma lista de parâmetros ( ... ) , seguida pelo marcador => e um corpo de função. Para funções de argumento único, os parênteses podem ser omitidos.
// Classical Function Expression
function addition ( a , b ) {
return a + b ;
} ;
// Implementation with arrow function
const addition = ( a , b ) => a + b ;
// With single argument, no parentheses required
const add5 = a => 5 + a ; Observe que, no exemplo acima, a função de seta addition é implementada com "corpo conciso", que não precisa de uma instrução de retorno explícita. Observe o omitido { } após o => .
Aqui está um exemplo com o usual "corpo do bloco". Incluindo as embalagens encaracoladas.
const arr = [ 'apple' , 'banana' , 'orange' ] ;
const breakfast = arr . map ( fruit => {
return fruit + 's' ;
} ) ;
console . log ( breakfast ) ; // ['apples', 'bananas', 'oranges']Contemplar! Há mais ...
As funções de seta não apenas diminuem o código. Eles estão intimamente relacionados a this comportamento de ligação.
A seta funciona o comportamento com this palavra -chave varia da das funções normais. Cada função no JavaScript define seu this contexto, mas as funções de seta capturam this valor do contexto de anexo mais próximo. Confira o seguinte código:
function Person ( ) {
// The Person() constructor defines `this` as an instance of itself.
this . age = 0 ;
setInterval ( function growUp ( ) {
// In non-strict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this . age ++ ;
} , 1000 ) ;
}
var p = new Person ( ) ; No ECMAScript 3/5, esse problema foi corrigido atribuindo o this a uma variável que poderia ser fechada.
function Person ( ) {
const self = this ;
self . age = 0 ;
setInterval ( function growUp ( ) {
// The callback refers to the `self` variable of which
// the value is the expected object.
self . age ++ ;
} , 1000 ) ;
}Como mencionado acima, as funções de seta capturam esse valor do contexto de anexo mais próximo; portanto, o código a seguir funciona conforme o esperado, mesmo com as funções de seta aninhadas.
function Person ( ) {
this . age = 0 ;
setInterval ( ( ) => {
setTimeout ( ( ) => {
this . age ++ ; // `this` properly refers to the person object
} , 1000 ) ;
} , 1000 ) ;
}
let p = new Person ( ) ;Leia mais sobre 'lexical this' nas funções de flecha aqui
O ES6 permite definir parâmetros padrão nas definições de função. Aqui está uma ilustração simples.
const getFinalPrice = ( price , tax = 0.7 ) => price + price * tax ;
getFinalPrice ( 500 ) ; // 850 ... O operador é referido como operador de spread ou repouso, dependendo de como e onde é usado.
Quando usado com qualquer itemerável, ele age para "espalhar" em elementos individuais:
const makeToast = ( breadType , topping1 , topping2 ) => {
return `I had ${ breadType } toast with ${ topping1 } and ${ topping2 } ` ;
} ; const ingredients = [ 'wheat' , 'butter' , 'jam' ] ;
makeToast ( ... ingredients ) ;
// "I had wheat toast with butter and jam"
makeToast ( ... [ 'sourdough' , 'avocado' , 'kale' ] ) ;
// "I had sourdough toast with avocado and kale"A propagação também é ótima para moldar um novo objeto de outros objetos:
const defaults = { avatar : 'placeholder.jpg' , active : false }
const userData = { username : 'foo' , avatar : 'bar.jpg' }
console . log ( { created : '2017-12-31' , ... defaults , ... userData } )
// {created: "2017-12-31", avatar: "bar.jpg", active: false, username: "foo"}Novas matrizes também podem ser moldadas expressivamente:
const arr1 = [ 1 , 2 , 3 ] ;
const arr2 = [ 7 , 8 , 9 ] ;
console . log ( [ ... arr1 , 4 , 5 , 6 , ... arr2 ] ) // [1, 2, 3, 4, 5, 6, 7, 8, 9] O outro uso comum de ... está reunindo todos os argumentos em uma matriz. Isso é referido como operador "REST".
function foo ( ... args ) {
console . log ( args ) ;
}
foo ( 1 , 2 , 3 , 4 , 5 ) ; // [1, 2, 3, 4, 5]O ES6 permite a declaração de literais de objetos, fornecendo sintaxe abreviada para inicializar as propriedades de variáveis e definir métodos de função. Também permite a capacidade de ter as chaves de propriedade calculadas em uma definição literal de objeto.
function getCar ( make , model , value ) {
return {
// with property value shorthand
// syntax, you can omit the property
// value if key matches variable
// name
make , // same as make: make
model , // same as model: model
value , // same as value: value
// computed values now work with
// object literals
[ 'make' + make ] : true ,
// Method definition shorthand syntax
// omits `function` keyword & colon
depreciate ( ) {
this . value -= 2500 ;
}
} ;
}
let car = getCar ( 'Kia' , 'Sorento' , 40000 ) ;
console . log ( car ) ;
// {
// make: 'Kia',
// model:'Sorento',
// value: 40000,
// makeKia: true,
// depreciate: function()
// } O ES6 tem um novo apoio a literais octais e binários. Aprendir um número com 0o ou 0O o converteria em valor octal. Dê uma olhada no seguinte código:
let oValue = 0o10 ;
console . log ( oValue ) ; // 8
let bValue = 0b10 ; // 0b or 0B for binary
console . log ( bValue ) ; // 2A destruição ajuda a evitar a necessidade de variáveis temporárias ao lidar com objetos e matrizes.
function foo ( ) {
return [ 1 , 2 , 3 ] ;
}
let arr = foo ( ) ; // [1,2,3]
let [ a , b , c ] = foo ( ) ;
console . log ( a , b , c ) ; // 1 2 3 function getCar ( ) {
return {
make : 'Tesla' ,
model : 'g95' ,
metadata : {
vin : '123abc' ,
miles : '12000'
}
} ;
}
const { make , model } = getCar ( ) ;
console . log ( make , model ) ; // Tesla g95
const { make , metadata : { miles } } = getCar ( ) ;
console . log ( make , miles ) ; // Tesla 12000
O ES6 permite usar super Método em objetos (sem classes) com protótipos. A seguir, é um exemplo simples:
const parent = {
foo ( ) {
console . log ( "Hello from the Parent" ) ;
}
}
const child = {
foo ( ) {
super . foo ( ) ;
console . log ( "Hello from the Child" ) ;
}
}
Object . setPrototypeOf ( child , parent ) ;
child . foo ( ) ; // Hello from the Parent
// Hello from the ChildO ES6 apresenta uma maneira mais fácil de adicionar interpolações que são avaliadas automaticamente.
`${ ... }` é usado para renderizar as variáveis.` Backtick é usado como delimitador. let user = 'Kevin' ;
console . log ( `Hi ${ user } !` ) ; // Hi Kevin!for...of iterados sobre objetos iteráveis, como a matriz. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname of nicknames ) {
console . log ( nickname ) ;
}
// di
// boo
// punkeyefor...in iterados em todas as propriedades enumeráveis de um objeto. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname in nicknames ) {
console . log ( nickname ) ;
}
// 0
// 1
// 2
// size O ES6 apresenta um novo conjunto de estruturas de dados chamadas Map e WeakMap . Agora, na verdade, usamos mapas em JavaScript o tempo todo. De fato, todo objeto pode ser considerado como um Map .
Um objeto é feito de chaves (sempre strings) e valores, enquanto que no Map , qualquer valor (objetos e valores primitivos) podem ser usados como uma chave ou um valor. Dê uma olhada neste pedaço de código:
const myMap = new Map ( ) ;
const keyString = "a string" ,
keyObj = { } ,
keyFunc = ( ) => { } ;
// setting the values
myMap . set ( keyString , "value associated with 'a string'" ) ;
myMap . set ( keyObj , "value associated with keyObj" ) ;
myMap . set ( keyFunc , "value associated with keyFunc" ) ;
myMap . size ; // 3
// getting the values
myMap . get ( keyString ) ; // "value associated with 'a string'"
myMap . get ( keyObj ) ; // "value associated with keyObj"
myMap . get ( keyFunc ) ; // "value associated with keyFunc"Map fraco
Um WeakMap é um mapa no qual as teclas são fracamente referenciadas, que não impede que suas teclas sejam coletadas de lixo. Isso significa que você não precisa se preocupar com vazamentos de memória.
Outra coisa a ser observada aqui- em WeakMap , em vez de Map todas as teclas devem ser um objeto .
Um WeakMap possui apenas quatro métodos delete(key) , has(key) , get(key) e set(key, value) .
const w = new WeakMap ( ) ;
w . set ( 'a' , 'b' ) ;
// Uncaught TypeError: Invalid value used as weak map key
const o1 = { } ,
o2 = ( ) => { } ,
o3 = window ;
w . set ( o1 , 37 ) ;
w . set ( o2 , "azerty" ) ;
w . set ( o3 , undefined ) ;
w . get ( o3 ) ; // undefined, because that is the set value
w . has ( o1 ) ; // true
w . delete ( o1 ) ;
w . has ( o1 ) ; // falseOs objetos de SET são coleções de valores exclusivos. Os valores duplicados são ignorados, pois a coleção deve ter todos os valores exclusivos. Os valores podem ser tipos primitivos ou referências de objetos.
const mySet = new Set ( [ 1 , 1 , 2 , 2 , 3 , 3 ] ) ;
mySet . size ; // 3
mySet . has ( 1 ) ; // true
mySet . add ( 'strings' ) ;
mySet . add ( { a : 1 , b : 2 } ) ; Você pode iterar sobre um conjunto de pedidos de inserção usando o método forEach ou o for...of loop.
mySet . forEach ( ( item ) => {
console . log ( item ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} ) ;
for ( let value of mySet ) {
console . log ( value ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} Os conjuntos também possuem os métodos delete() e clear() .
Conjunto fraco
Semelhante ao WeakMap , o objeto WeakSet permite armazenar objetos fracamente mantidos em uma coleção. Um objeto no WeakSet ocorre apenas uma vez; É único na coleção do fraco.
const ws = new WeakSet ( ) ;
const obj = { } ;
const foo = { } ;
ws . add ( window ) ;
ws . add ( obj ) ;
ws . has ( window ) ; // true
ws . has ( foo ) ; // false, foo has not been added to the set
ws . delete ( window ) ; // removes window from the set
ws . has ( window ) ; // false, window has been removedO ES6 apresenta uma nova sintaxe de classe. Uma coisa a observar aqui é que a classe ES6 não é um novo modelo de herança orientado a objetos. Eles apenas servem como um açúcar sintático sobre a herança baseada em protótipo existente de JavaScript.
Uma maneira de olhar para uma classe no ES6 é apenas uma nova sintaxe para trabalhar com protótipos e funções de construtor que usaríamos no ES5.
Funções definidas usando as funções static de palavras -chave estáticas/classe na classe.
class Task {
constructor ( ) {
console . log ( "task instantiated!" ) ;
}
showId ( ) {
console . log ( 23 ) ;
}
static loadAll ( ) {
console . log ( "Loading all tasks.." ) ;
}
}
console . log ( typeof Task ) ; // function
const task = new Task ( ) ; // "task instantiated!"
task . showId ( ) ; // 23
Task . loadAll ( ) ; // "Loading all tasks.."estende e super em aulas
Considere o seguinte código:
class Car {
constructor ( ) {
console . log ( "Creating a new car" ) ;
}
}
class Porsche extends Car {
constructor ( ) {
super ( ) ;
console . log ( "Creating Porsche" ) ;
}
}
let c = new Porsche ( ) ;
// Creating a new car
// Creating Porsche extends permitem que a classe infantil herde da classe pai no ES6. É importante observar que o construtor derivado deve chamar super() .
Além disso, você pode chamar o método da classe pai nos métodos da classe infantil usando super.parentMethodName()
Leia mais sobre as aulas aqui
Algumas coisas a ter em mente:
function ao definir funções dentro de uma definição de classe. Um Symbol é um tipo de dados único e imutável introduzido no ES6. O objetivo de um símbolo é gerar um identificador exclusivo, mas você nunca pode obter acesso a esse identificador.
Veja como você cria um símbolo:
const sym = Symbol ( "some optional description" ) ;
console . log ( typeof sym ) ; // symbol Observe que você não pode usar new com Symbol(…) .
Se um símbolo for usado como uma propriedade/chave de um objeto, ele é armazenado de uma maneira especial que a propriedade não aparecerá em uma enumeração normal das propriedades do objeto.
const o = {
val : 10 ,
[ Symbol ( "random" ) ] : "I'm a symbol" ,
} ;
console . log ( Object . getOwnPropertyNames ( o ) ) ; // val Para recuperar as propriedades do símbolo de um objeto, use Object.getOwnPropertySymbols(o)
Um iterador acessa os itens de uma coleção, um de cada vez, enquanto acompanha sua posição atual dentro dessa sequência. Ele fornece um método next() que retorna o próximo item na sequência. Este método retorna um objeto com duas propriedades: feito e valor.
O ES6 possui Symbol.iterator , que especifica o iterador padrão para um objeto. Sempre que um objeto precisa ser iterado (como no início de um loop para um loop), seu método @@ iterator é chamado sem argumentos, e o iterador retornado é usado para obter os valores a serem iterados.
Vejamos uma matriz, que é um iterável, e o iterador que ele pode produzir para consumir seus valores:
const arr = [ 11 , 12 , 13 ] ;
const itr = arr [ Symbol . iterator ] ( ) ;
itr . next ( ) ; // { value: 11, done: false }
itr . next ( ) ; // { value: 12, done: false }
itr . next ( ) ; // { value: 13, done: false }
itr . next ( ) ; // { value: undefined, done: true } Observe que você pode escrever iteradores personalizados definindo obj[Symbol.iterator]() com a definição do objeto.
As funções do gerador são um novo recurso no ES6 que permite que uma função gere muitos valores ao longo do tempo, retornando um objeto que pode ser iterado para extrair valores da função um valor por vez.
Uma função de gerador retorna um objeto iterável quando é chamado. É escrito usando a nova sintaxe * , bem como a nova palavra -chave de yield introduzida no ES6.
function * infiniteNumbers ( ) {
let n = 1 ;
while ( true ) {
yield n ++ ;
}
}
const numbers = infiniteNumbers ( ) ; // returns an iterable object
numbers . next ( ) ; // { value: 1, done: false }
numbers . next ( ) ; // { value: 2, done: false }
numbers . next ( ) ; // { value: 3, done: false }Cada rendimento de tempo é chamado, o valor produzido se torna o próximo valor na sequência.
Além disso, observe que os geradores calculam seus valores rendidos sob demanda, o que lhes permite representar eficientemente sequências que são caras de calcular ou mesmo sequências infinitas.
O ES6 tem apoio nativo às promessas. Uma promessa é um objeto que está aguardando a conclusão de uma operação assíncrona e, quando essa operação é concluída, a promessa é cumprida (resolvida) ou rejeitada.
A maneira padrão de criar uma promessa é usando o new Promise() que aceita um manipulador que recebe duas funções como parâmetros. O primeiro manipulador (normalmente nomeado resolve ) é uma função a ser chamada com o valor futuro quando estiver pronto; e o segundo manipulador (normalmente nomeado reject ) é uma função a chamar para rejeitar a promessa se não puder resolver o valor futuro.
const p = new Promise ( ( resolve , reject ) => {
if ( /* condition */ ) {
resolve ( /* value */ ) ; // fulfilled successfully
} else {
reject ( /* reason */ ) ; // error, rejected
}
} ) ; Toda promessa tem um método chamado then que leva um par de retornos de chamada. O primeiro retorno de chamada é chamado se a promessa for resolvida, enquanto a segunda for chamada se a promessa for rejeitada.
p . then ( ( val ) => console . log ( "Promise Resolved" , val ) ,
( err ) => console . log ( "Promise Rejected" , err ) ) ; Retornar um valor then retornos de chamada passará o valor para o próximo then o retorno de chamada.
const hello = new Promise ( ( resolve , reject ) => { resolve ( "Hello" ) } ) ;
hello . then ( ( str ) => ` ${ str } World` )
. then ( ( str ) => ` ${ str } !` )
. then ( ( str ) => console . log ( str ) ) // Hello World!Ao devolver uma promessa, o valor resolvido da promessa será passado para o próximo retorno de chamada para encadeá -los efetivamente. Esta é uma técnica simples para evitar o "inferno de retorno de chamada".
const p = new Promise ( ( resolve , reject ) => { resolve ( 1 ) } ) ;
const eventuallyAdd1 = ( val ) => new Promise ( ( resolve , reject ) => { resolve ( val + 1 ) } ) ;
p . then ( eventuallyAdd1 )
. then ( eventuallyAdd1 )
. then ( ( val ) => console . log ( val ) ) ; // 3