Guia do artigo:

Default param

Permite definir um valor pré-definido caso o parâmetro não seja preenchido ou receba o valor undefined.

Visão geral

Em uma função em JavaScript ou qualquer outra linguagem de programação é comum a necessidade de escrever funções que possuam algum tipo de valor pré-definido em alguns de seus argumentos, por exemplo:

function createElement (tag, props = {}) {
  console.log(tag, props)
  ...
}

createElement('p')
// p {}

createElement('p', { className: 'text textarea', children: 'Design for Human' })
// p { classNames: 'text textarea', children: 'Design for Human' }

Neste exemplo a função createElement recebe uma string como o nome do elemento que deverá ser criado e em seguida opcionalmente é informado os propriedades deste elemento, perceba que quando nenhuma props e definida a função define o valor do argumento como um objeto vazio.

Sintaxe

(parametro [ = valor-padrao ]) => instrucao

Na prática

Exemplo 1

Neste exemplo utilizamos a função soma e atribuímos a seus parâmetros valores pré-definidos caso não sejam preenchidos.

function total (a = 10, b = 20) {
  return a + b
}

console.log(total()) // 30
console.log(total(5, 5)) // 10

Exemplo 2

É possível definir valores pré-definidos para arrow function como no exemplo abaixo:

const addMensagem = (mensagem, data = Date.now()) => ({
  mensagem,
  data
})

console.log(addMensagem('Oi, tudo bem?')) // { mensagem: "Oi, tudo bem?", data: 1532978959897 }

Exemplo 3

É possível definir valores padrão para parâmetros a partir de funções como no exemplo abaixo:

function getTotalNotificacoes () {
  ...
}

function notificar (mensagem = getTotalNotificacoes()) {
  return 'total de notificações: ' + mensagem
}

console.log(notificar()) // total de notificações: 4

Exemplo 4

É possível também utilizar os parâmetros pré-definidos em métodos de classes, no exemplo abaixo podemos ver melhor como este recurso do JavaScript é utilizado.

class Pessoa {
  constructor (nome, cpf= '999.999.999-99') {
    this.nome = nome
    this.cpf = cpf
  }
}

const p1 = new Pessoa('bruno')

console.log(p1.cpf) // 999.999.999-99

Exemplo 5

Neste exemplo temos uma função que calcula o pagamento de um associado, caso não seja informado o valor de comissão e desconto, o mesmo será definido como zero e desconsiderado.

/**
 * Esta função calcula a comissão e desconto de um associado
 *
 * @param  bruto valor bruto de pagamento
 * @param  [comissao] porcentagem (%) de comissão
 * @param  [desconto] porcentagem (%) de desconto
 * @returns 
 */
function calculaPagamento (bruto, comissao = 0, desconto = 0) {
  let total = bruto

  // adiciona ao total o valor da comissão
  if (comissao > 0) {
    total += (bruto / 100) * comissao
  }

  // remove o valor que deverá ser descontado
  if (desconto > 0) {
    total -= (bruto / 100) * desconto
  }

  return total
}

const bruto = calculaPagamento(1000, 50, 10)

console.log(bruto)

// 1400

Arrow function

É uma forma sucinta de escrever funções anônimas em JavaScript.

Visão geral

As arrow function podem ser utilizadas em todos os cenários onde as função são aplicadas como por exemplo callbacks. Sua diferença pratica se dá na ausência de referência do this de seu escopo e em sintaxe mais curta.

Considere por exemplo que seja necessário efetuar um relatorio onde você precisa somar o valor de todos os carros que tem valor maior que R$14.000,00. Para execução desta tarefa utilizamos apenas os métodos filter, map e reduce.

const carros = [
  { id: 1, modelo: 'Corsa', marca: 'Chevrolet', preco: 18000 },
  { id: 2, modelo: 'Punto', marca: 'Fiat', preco: 12000 },
  { id: 3, modelo: 'Gol', marca: 'Volkswagen', preco: 14000 },
  { id: 4, modelo: 'Saveiro', marca: 'Volkswagen', preco: 20000 },
  { id: 5, modelo: 'Uno', marca: 'Fiat', preco: 12000 },
  { id: 6, modelo: 'Onix', marca: 'Chevrolet', preco: 25000 },
  { id: 7, modelo: 'Palio', marca: 'Fiat', preco: 13000 },
  { id: 8, modelo: 'Prisma', marca: 'Chevrolet', preco: 15000 },
  { id: 9, modelo: 'Logan', marca: 'Renault', preco: 15000 }
]

const data = carros
  .filter(item => item.preco >= 14000)
  .map(item => item.preco)
  .reduce((anterior, atual) => anterior + atual, 0)

const total = data.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })

console.log(total)
// R$ 107,000.00

Perceba que as arrow functions tornaram o código mais sucinto graças a sua sintaxe curta, ao invés de ter que declarar uma função como callback como no fragmento de código abaixo.

  .filter(function (item) {
    return item.preco >= 14000
  })

Sintaxe

(parametro1, parametro2, ..., parametroX) => expressao
  • parametro: valores passados para dentro do escopo da função.
  • expressao: bloco de código que pode retornar um valor ao final da execução.

Na prática

Exemplo 1

No exemplo abaixo a função soma recebe dois parâmetros e retorna a soma desses. Podemos declará-la de forma tradicional, como a seguir:

function soma (a, b) {
  return a + b
}

console.log(soma(1, 2)) // 3

Esta mesma função pode ser escrita com uma arrow function:

const soma = (a, b) => {
  return a + b
}

console.log(soma(1, 2)) // 3

E possível também declará-la utilizando a sintaxe curta:

const soma = (a, b) => a + b

console.log(soma(1, 2)) // 3

Exemplo 2

Neste exemplo temos uma função que recebe por parâmetro uma frase e separa cada palavra em uma lista retornando-a como resultado.

A seguir podemos ver esta função escrita de forma tradicional:

const frase = 'Eu curto a DevMedia'

function separaFrase (frase) {
  return frase.split(' ')
}

console.log(separaFrase(frase)) // [ 'Eu', 'curto', 'a', 'DevMedia' ]

Agora temos essa mesma função utilizando arrow functions:

const frase = 'Eu curto a DevMedia'

const separaFrase = (texto) => {
  return texto.split(' ')
}

console.log(separaFrase(frase)) // [ 'Eu', 'curto', 'a', 'DevMedia' ]

Quando há apenas um parâmetro na função não é necessário o uso de parênteses na expressão, como no exemplo abaixo:

const separaFrase = texto => texto.split(' ')

Exemplo 3

As arrow functions podem ser utilizadas para tornar a sintaxe de métodos que recebem callback mais simples. No exemplo abaixo utilizamos o método find para encontrar em uma lista o usuário cujo id é igual a 2:

const usuarios = [
  { id: 1, nome: 'Maria da Silva' },
  { id: 2, nome: 'João Fernando' },
  { id: 3, nome: 'Pedro dos Santos' }
]

const usuario = usuarios.find(usuario => usuario.id === 2)

console.log(usuario.nome) // João Fernando

As arrow functions funcionam em métodos que recebam callback como por exemplo o map, reduce e filter.

Exemplo 4

Neste exemplo temos a função Contador que exibe um log com o número de segundos desde o momento em que foi instanciada. Vamos ver primeiro esta função utilizando a sintaxe disponível até o ECMAScript 5:

function Contador () {
  var self = this

  self.valorAtual = 0

  setInterval(function () {
    self.valorAtual++
    console.log(self.valorAtual)
  }, 1000)
}

Neste exemplo utilizamos a variável self na linha 2 para armazenar uma referência ao escopo pai (Contador) para acessá-lo dentro de outras funções, como é feito dentro do escopo do setTimeout. Entre as linhas 6 e 9 aumentamos o valorAtual em 1 e em seguida exibimos um log com valor do self.valorAtual.

No exemplo abaixo reescrevemos a mesma função (Contador) utilizando arrow function, pois não possuem bind do this como as funções tradicionais, evitando o uso de variáveis para armazenar o escopo de uma função pai, prática comum até o ES5:

function Contador () {
  this.valorAtual = 0

  setInterval(() => {
    this.valorAtual++
    console.log(this.valorAtual)
  }, 1000)
}

A partir deste exemplo podemos concluir que, além de ter uma sintaxe mais simples, as arrow functions são uma ferramenta poderosa quando é necessário acessar o escopo da função pai.

Exemplo 5

É possível utilizar arrow function para retornar objetos, prática comum com as action creators do Redux. No exemplo abaixo podemos ver como esse processo é feito:

const addTodo = (mensagem) => ({
  mensagem,
  isComplete: false
})

console.log(addTodo('Olá mundo!!')) // { mensagem: 'Olá mundo!!', isComplete: false }

Compatibilidade

Engine Versão Minima
Node.JS ( V8) 6.4.0
Safari ( WebKit) 11.1
Chrome ( V8) 68
Microsoft Edge ( ChakraCore) 17
Firefox ( Gecko) 61

Nota: O Opera utiliza atualmente grande parte do código do Chrome como base para o seu próprio desenvolvimento e por isso ele não é mencionado nesta listagem.

Confira também