Modern JavaScript

JavaScript Moderno (ES6+)

O ES6 e as versões que se seguiram transformaram o JavaScript de uma linguagem de script peculiar em um prazer de escrever. Aqui estão os recursos que você usará todos os dias.

intermediate15 min readUpdated 15 de set. de 2026
js
// cart.js
const items = [
  { name: "Keyboard", price: 80, qty: 1 },
  { name: "Mouse", price: 40, qty: 2 },
];

const total = items
  .map(({ price, qty }) => price * qty)
  .reduce((sum, n) => sum + n, 0);

console.log(`Total: $${total}`);
Lançado
Junho de 2015
Também conhecido como
ES2015 / ES6
Desde então
Um lançamento por ano
Maiores ganhos
Escopo, módulos, async
Principais adições
Arrow, destructuring, spread
Compatibilidade
Universal em navegadores modernos

Pratico

Experimente métodos de array modernos

Altere os números e observe o total ser atualizado.

Experimente métodos de array modernos

Altere os números e observe o total ser atualizado.

Por que importa

Por que o JavaScript moderno é importante

Menos cerimônia

Destructuring, shorthand e template literals removem o boilerplate para que a intenção se destaque em vez do ruído da sintaxe.

Escopo mais seguro

let e const com escopo de bloco substituem o var, eliminando toda uma classe de bugs de hoisting e globais acidentais.

Módulos reais

import e export deram ao JavaScript um sistema de módulos padrão, tornando finalmente naturais o compartilhamento de código e o tree-shaking.

O panorama completo

Três mudanças que mudaram tudo

O ES6 não trouxe apenas nova sintaxe. Ele mudou a forma como o escopo funciona, como o código é organizado e como os dados fluem através de um programa.

Declarações

let, const, arrow

Escopo de bloco e funções concisas mudaram a forma como o código cotidiano é escrito e lido.

Manipulação de dados

Destructuring, spread

Extrair valores e combiná-los tornou-se expressivo em vez de repetitivo.

Composição

Módulos, classes

Módulos padrão e a sintaxe de classes tornaram programas maiores mais fáceis de organizar e compartilhar.

ES6+ em resumo

Os recursos que você usará diariamente

let & const

Bindings com escopo de bloco que tornam as variáveis previsíveis.

Arrow functions

Sintaxe de função curta com this léxico, perfeita para callbacks.

Template literals

Strings de múltiplas linhas e interpolação com crases e ${}.

Destructuring

Desempacote arrays e objetos em variáveis em uma única expressão.

Spread & rest

Expanda valores em locais ou colete-os em um só, usando os mesmos três pontos.

Módulos

Divida o código em arquivos com import e export em vez de globais.

Uma breve historia

A jornada do ES5 até hoje

  1. 2009

    ES5

    Strict mode, JSON e métodos de array como map e filter tornam-se a base.

    09
  2. 2015

    ES6 / ES2015

    A maior atualização de todas — let, const, arrows, classes, promises, módulos e mais.

    15
  3. 2017

    async / await

    O código assíncrono finalmente é lido como código síncrono.

    17
  4. 2020

    Optional chaining

    ?. e ?? removem montanhas de verificações defensivas de null.

    20
  5. Hoje

    Lançamentos anuais

    O TC39 lança uma nova edição do padrão, retrocompatível, todo mês de junho.

    Hoje

O guia completo

JavaScript Moderno (ES6+): Tudo que voce precisa saber

O que é ES6+?

Em junho de 2015, o JavaScript recebeu a sua maior atualização de todos os tempos. O ECMAScript 2015, mais conhecido como ES6, adicionou block scoping, arrow functions, classes, modules, promises e muito mais. O comitê que mantém a linguagem comprometeu-se, então, a lançar uma nova edição a cada ano, e “ES6+” tornou-se a abreviação para toda essa era moderna.

Você não precisa aprender cada recurso. Um pequeno grupo deles representa a vasta maioria do código escrito no dia a dia, e é neles que este guia foca. O tema central de todos eles é simples: diga o que você quer com menos cerimônia.

let e const

O recurso mais antigo é também o mais importante. var possui escopo de função e sofre hoisting de maneiras que surpreendem as pessoas. let e const possuem escopo de bloco, portanto, existem apenas dentro do { } mais próximo.

// scope.js
if (true) {
  let message = "inside";
  const limit = 10;
}

// message and limit are not defined out here

const evita a reatribuição do binding, o que torna sua intenção óbvia: este nome não apontará para outro lugar. Ele não congela o valor, então um array const ainda pode ser mutado. Use const por padrão, let quando a reatribuição for necessária, e trate var como história.

Arrow functions

Arrow functions são uma sintaxe mais curta com uma diferença comportamental importante: elas não possuem seu próprio this. Elas herdam o this do escopo ao redor, que é quase sempre o que você deseja em callbacks.

// arrows.js
const add = (a, b) => a + b;

const square = (n) => {
  return n * n;
};

const names = ["Ada", "Grace", "Linus"];
const upper = names.map((name) => name.toUpperCase());

Quando o corpo é uma única expressão, as chaves e o return podem ser omitidos. Parênteses em volta de um único parâmetro são opcionais. Como arrow functions capturam o this, elas são ideais para event handlers e métodos de array, mas não são adequadas para métodos de objeto que precisam de seu próprio this.

Template literals

As crases criam strings que abrangem múltiplas linhas e interpolam expressões com ${ }.

// message.js
const name = "Ada";
const role = "engineer";

const greeting = `Hello, ${name}!
You are logged in as a ${role}.`;

Template literals também suportam tagged templates, onde uma função recebe as partes literais e os valores interpolados separadamente. Esse mecanismo serve de base para muitas bibliotecas de estilização e templating.

Destructuring

O destructuring desempacota valores de arrays e objetos em variáveis, o que elimina grande parte do acesso repetitivo a propriedades.

// destructure.js
const user = { name: "Ada", age: 36, city: "London" };
const { name, age, city = "Unknown" } = user;

const coords = [51.5, -0.12];
const [lat, lng] = coords;

function greet({ name }) {
  return `Hello, ${name}`;
}

Você pode renomear variáveis durante o destructuring (const { name: userName } = user), definir valores padrão e fazer o destructuring diretamente na lista de parâmetros de uma função — um padrão utilizado constantemente com props do React e objetos de configuração.

Spread e rest

Os mesmos três pontos desempenham duas funções complementares, dependendo de onde aparecem.

// spread.js
const a = [1, 2, 3];
const b = [4, 5];

const combined = [...a, ...b];       // spread: expand
const copy = { ...user, age: 37 };   // shallow clone + override

function sum(...numbers) {           // rest: collect
  return numbers.reduce((t, n) => t + n, 0);
}

O Spread copia elementos para um novo array ou objeto, sendo a base para atualizações imutáveis. O Rest agrupa os argumentos ou elementos restantes em um único array. Juntos, eles tornam o trabalho com coleções muito mais agradável.

Parâmetros padrão e shorthand

Funções podem declarar valores padrão, e literais de objeto podem usar shorthand quando o nome da propriedade coincide com o de uma variável.

// config.js
function connect({ host = "localhost", port = 8080 } = {}) {
  return `${host}:${port}`;
}

const name = "Ada";
const user = { name, greet() { return `Hi, ${this.name}`; } };

Os valores padrão são avaliados apenas quando o argumento é undefined, que geralmente é o comportamento desejado. Propriedades e métodos shorthand reduzem o ruído em códigos com uso intenso de objetos.

Optional chaining e nullish coalescing

Esses dois operadores, adicionados em 2020, eliminaram montanhas de verificações defensivas.

// safe.js
const city = user?.address?.city;
const name = input ?? "anonymous";

user?.profile?.onLogin?.();

?. faz um short-circuit para undefined se o valor à sua esquerda for null ou undefined. ?? fornece um fallback apenas quando o lado esquerdo é null ou undefined — ao contrário de ||, ele não trata 0, "" ou false como valores ausentes.

Métodos de Array

O protótipo de array é repleto de métodos que descrevem a intenção em vez da mecânica de repetição.

// arrays.js
const products = [
  { name: "Keyboard", price: 80, inStock: true },
  { name: "Mouse", price: 40, inStock: false },
  { name: "Cable", price: 10, inStock: true },
];

const names = products.map((p) => p.name);
const cheap = products.filter((p) => p.price < 50);
const total = products.reduce((sum, p) => sum + p.price, 0);
const available = products.some((p) => p.inStock);
const allCheap = products.every((p) => p.price < 100);
const mouse = products.find((p) => p.name === "Mouse");

map transforma, filter seleciona, reduce reduz uma lista a um único valor, find retorna a primeira correspondência, e some/every testam uma condição. Eles podem ser encadeados, não mutam o array original e a leitura parece a descrição do que você deseja alcançar.

Módulos

Os ES modules permitem que você divida o código entre vários arquivos e compartilhe apenas o que desejar.

// math.js
export function add(a, b) {
  return a + b;
}

export const PI = 3.14159;
export default function subtract(a, b) {
  return a - b;
}
// app.js
import subtract, { add, PI } from "./math.js";

As named exports podem ser várias por arquivo e são importadas pelo nome. Já a default export é um único valor principal. Os módulos possuem seu próprio escopo, são avaliados apenas uma vez e permitem que os bundlers removam código não utilizado através de tree-shaking.

Classes

Classes fornecem uma sintaxe clara para código orientado a objetos, construída sobre o sistema de protótipos existente do JavaScript.

// user.js
class User {
  #secret = "hidden"; // private field

  constructor(name) {
    this.name = name;
  }

  get greeting() {
    return `Hello, ${this.name}`;
  }

  static create(name) {
    return new User(name);
  }
}

class Admin extends User {
  constructor(name) {
    super(name);
    this.role = "admin";
  }
}

extends e super lidam com a herança, static define métodos na própria classe e # marca campos verdadeiramente privados. Por baixo dos panos, ainda são protótipos, mas a sintaxe é muito mais fácil de ler.

Outros recursos que valem a pena conhecer

  • Map e Set para coleções com chaves e valores únicos, com semânticas melhores do que objetos e arrays comuns para essas tarefas.
  • for…of para iterar sobre arrays, strings, maps, sets e qualquer iterável.
  • Exponenciação com **, portanto 2 ** 10 substitui Math.pow(2, 10).
  • Iterators e generators para sequências preguiçosas (lazy sequences), iterações customizadas e funções pausáveis.
  • Object.entries / fromEntries para converter entre objetos e arrays de pares.

Melhores práticas

  • Use const por padrão; utilize let apenas quando houver reatribuição.
  • Prefira arrow functions para callbacks e funções regulares para métodos que precisem de this.
  • Utilize desestruturação nos parâmetros para tornar a estrutura necessária explícita.
  • Use o operador spread para atualizações imutáveis em vez de mutar dados compartilhados.
  • Utilize ?. e ?? antes de escrever guards aninhados.
  • Prefira métodos de array em vez de loops manuais ao transformar dados.
  • Mantenha os módulos pequenos e exporte a menor superfície possível.

Erros comuns

  • Assumir que const torna um objeto imutável — ele apenas impede a reatribuição (rebinding).
  • Usar uma arrow function como método de um objeto e perder o this.
  • Usar || para valores padrão quando 0 ou "" são valores válidos; use ??.
  • Fazer o spread de apenas um nível e esperar um deep clone.
  • Misturar require e import no mesmo sistema de módulos sem entender a interoperabilidade.
  • Encadear métodos de array em excesso, criando um pipeline ilegível.

Próximos passos

A sintaxe moderna é o vocabulário; o DOM e o JavaScript assíncrono são onde você coloca esse conhecimento em prática. Assim que as promises e os módulos se tornarem naturais, a Fetch API transformará essas habilidades em aplicações reais.

Acessando dados aninhados

Optional chaining e nullish coalescing substituem cadeias de verificações &&.

Prefira
const city =
  user?.address?.city ?? "Unknown";
Evite
const city =
  user && user.address &&
  user.address.city
    ? user.address.city
    : "Unknown";

Transformando uma lista

map e reduce expressam a intenção e evitam variáveis acumuladoras manuais.

Prefira
const names = users
  .filter((u) => u.active)
  .map((u) => u.name);
Evite
const names = [];
for (let i = 0; i < users.length; i++) {
  if (users[i].active) {
    names.push(users[i].name);
  }
}

Perguntas frequentes

Perguntas frequentes

Keep learning

Related topics from the roadmap.

$ comecar a aprender

Pronto para aprender ES6+ Features?

Nosso tutorial interativo te guia por ES6+ Features passo a passo — com quizzes e codigo real que voce pode executar no navegador.