Funções normais
Em JavaScript, funções normais podem ser definidas ou declaradas usando o function
palavra-chave, seguida pelo nome da função, um par de parênteses para parâmetros (se houver) e o corpo da função.
Por exemplo:
1 |
function greeting() { |
2 |
return "Hello world"; |
3 |
}
|
greeting
é uma função simples que retorna a string “Hello World”.
Parâmetros de Função
As funções podem aceitar zero, um ou vários parâmetros, dependendo dos seus requisitos.
Uma função com zero parâmetros
1 |
function greeting() { |
2 |
return "Hello world"; |
3 |
}
|
Uma função com um parâmetro
1 |
function greeting(name) { |
2 |
return "Hello " + name; |
3 |
}
|
Uma função com vários parâmetros
1 |
function greeting(firstName, lastName) { |
2 |
return "Hello " + firstName + " " + lastName; |
3 |
}
|
Funções anônimas
Funções anônimas são funções sem nome. Muitas vezes são atribuídos a variáveis ou passados como argumentos para outras funções. Uma função anônima se parece com isto:
1 |
let greeting = function() { |
2 |
return "Hello world"; |
3 |
};
|
Mesmo que a função não tenha nome, você pode invocá-la com a variável à qual está atribuída, assim:
1 |
console.log(greeting()) |
2 |
// Hello world
|
Funções de seta
As funções de seta fornecem uma maneira simplificada e concisa de declarar funções, tornando o código legível.
Os atributos a seguir definem funções de seta.
-
As funções de seta usam uma seta grossa
(=>)
ao invés defunction
palavra-chave. - As funções de seta fornecem expressões de função mais curtas.
-
Uma função de seta não cria a sua própria
this
,arguments
ousuper
e, portanto, não pode ser usado como método na criação de objetos. - Você não pode usar uma função de seta para criar novas instâncias de objetos, pois elas não possuem o
prototype
propriedade.
A sintaxe de uma função de seta é semelhante a esta:
1 |
let myFunction = (p, p1, p2, ...pnth) => { |
2 |
// define function logic here
|
3 |
};
|
4 |
|
Para converter nosso exemplo anterior da função de saudação anônima em uma função de seta, precisamos apenas remover o function
palavra-chave e adicione uma seta =>
antes do corpo da função. A função de saudação como uma função de seta ficaria assim:
1 |
let greeting = () => { |
2 |
return "Hello world"; |
3 |
|
4 |
}
|
Se a função não tiver parâmetros, podemos simplificar ainda mais a expressão removendo os colchetes e os parênteses. Portanto, nossa função ficará assim.
1 |
let greeting = () => "Hello World"; |
Os parênteses não podem ser omitidos mesmo que não haja parâmetros.
Funções com parâmetros
Se uma função de seta contém parâmetros, eles são adicionados entre parênteses, assim como nas funções regulares.
1 |
let greeting = (name) => "Hello " + name ; |
2 |
|
3 |
console.log(greeting("Esther")); //output //Hello Esther |
Se tivermos apenas um único parâmetro como o acima, podemos encurtar ainda mais a função removendo os parênteses.
1 |
let greeting = name => "Hello " +name ; |
Uma função de seta com vários parâmetros.
1 |
let greeting = (name,timeofDay ) => "Hello "+ name + ", How is your " + timeofDay ; |
2 |
console.log(greeting("Esther","evening")); |
3 |
// output // Hello Esther, How is your evening
|
Declarações Múltiplas
Às vezes, as funções possuem múltiplas expressões ou instruções; neste caso, declarações ou expressões devem ser colocadas entre chaves.
1 |
let greeting = (name, timeOfDay) => { |
2 |
let message = "Good " + timeOfDay + ", " + name + "!"; |
3 |
let today = new Date(); |
4 |
let dayOfWeek = today.toLocaleDateString('en-US', { weekday: 'long' }); |
5 |
|
6 |
return message + " Happy " + dayOfWeek + "!"; |
7 |
};
|
8 |
|
9 |
console.log(greeting("Esther","morning")) |
Aqui, adicionamos uma mensagem que obtém o dia da semana atual usando o objeto Date e retorna uma mensagem de saudação personalizada dependendo do dia.
A saída será:
1 |
Good morning, Esther! Happy Tuesday! |
Retorno Implícito vs Explícito
Escrevemos alguns exemplos que utilizaram o conceito de implícito e explícito retornar. O retorno implícito é visto quando usamos uma única expressão, e o resultado é retornado automaticamente sem usar a palavra-chave return.
Retorno implícito significa que o return
a palavra-chave está automaticamente implícita; portanto, não há necessidade de chaves e return
palavra-chave. Nossa função de saudação abaixo usa retorno implícito.
1 |
let greeting = (name,timeofDay ) => "Hello "+ name + ", How is your " + timeofDay ; |
2 |
|
3 |
greeting("Esther","evening") |
O retorno explícito, por outro lado, envolve o uso do return
palavra-chave para especificar o que deve ser retornado. Vamos modificar nossa função de saudação para demonstrar o retorno explícito. Adicione as chaves e inclua o return
declaração.
1 |
let greeting = (name, timeOfDay) => { |
2 |
return "Good " + timeOfDay + ", " + name + "!"; |
3 |
};
|
4 |
greeting("Esther","morning") |
Funções de seta e this
Contexto
As funções de seta não têm as suas próprias this
contexto. O escopo anexo determina o valor de this
. Considere o exemplo abaixo.
1 |
const myObject = { |
2 |
name:"Mike", |
3 |
grade:8, |
4 |
ArrowMethod : () => `${this.name}, ${this.grade}` |
5 |
}
|
6 |
|
7 |
const result = myObject.ArrowMethod() |
8 |
console.log(result) //output //undefined |
A saída será undefined
porque como a função arrow é definida dentro de um objeto, a função arrow irá capturar o valor de this
do contexto envolvente, ou seja, janela em um ambiente de navegador ou objeto global em um ambiente Node JS. E como o escopo global não tem um name
ou grade
propriedade, a saída de this.name
e this.grade
torna-se indefinido.
Em uma função regular, o valor de this
é determinado pela forma como a função é chamada, portanto, usar uma função normal fornecerá os resultados pretendidos.
1 |
const myObject = { |
2 |
name:"Mike", |
3 |
grade:8, |
4 |
ArrowMethod : function() { |
5 |
return `${this.name}, ${this.grade}`; |
6 |
}
|
7 |
}
|
8 |
|
9 |
const result = myObject.ArrowMethod() |
10 |
console.log(result) //output //Mike, 8 |
Benefícios e aplicações das funções de seta
As funções de seta no desenvolvimento web melhoram a legibilidade do código e reduzem a sintaxe desnecessária. Outras situações comuns em que as funções de seta são aplicáveis são na programação funcional e nas promessas de Javascript.
Usando funções de seta para transformar matrizes
Funções de seta são comumente usadas em programação funcional. A programação funcional envolve o uso de funções de ordem superior, como map()
, filter(),
e reduce()
.
Usando a função map()
A função map é um método embutido que transforma um array em outro, aplicando uma operação específica em cada elemento do array original. Por exemplo, suponha que temos um array de nomes e precisamos de uma mensagem de saudação personalizada para cada nome do array.
1 |
let names = ["Alice", "Bob", "Charlie"]; |
Vamos escrever uma função greeting
e retornar uma saudação personalizada para cada nome no names
variedade . Sem usar funções de seta, a função ficaria assim:
1 |
let greeting = function (name, timeOfDay) { |
2 |
return "Good " + timeOfDay + ", " + name; |
3 |
}
|
4 |
|
5 |
|
6 |
let timeOfDay = "evening"; |
7 |
|
8 |
let greetings = []; |
9 |
|
10 |
for (let i = 0; i < names.length; i++) { |
11 |
greetings.push(greeting(names[i], timeOfDay)); |
12 |
}
|
13 |
|
14 |
console.log(greetings) |
A saída será:
1 |
[
|
2 |
'Good evening, Esther', |
3 |
'Good evening, Carol', |
4 |
'Good evening, Amber' |
5 |
]
|
Podemos realizar a mesma transformação usando o map()
funções de função e seta, reduzindo a sintaxe e tornando o código legível.
1 |
let greeting = (name, timeOfDay) => "Good " + timeOfDay + ", "+ name; |
2 |
let names = ["Esther" , "Carol" ,"Amber"] |
3 |
let timeOfDay = "evening" |
4 |
|
5 |
let greetings = names.map(name =>greeting(name,timeOfDay)); |
6 |
|
7 |
console.log(greetings) |
Usando a função filter()
O filter()
function é outro método JavaScript embutido que cria um novo array com base em uma condição transmitida aos elementos originais do array. Por exemplo, suponha que temos uma variedade de produtos e precisamos filtrar com base em produtos com classificação superior a 3.
1 |
const produtos = [ |
2 |
{ id: 1, title: "Product A", rating: 4 }, |
3 |
{ id: 2, title: "Product B", rating: 2 }, |
4 |
{ id: 3, title: "Product C", rating: 3 }, |
5 |
{ id: 4, title: "Product D", rating: 5 }, |
6 |
{ id: 5, title: "Product E", rating: 1 } |
7 |
];
|
Vamos aplicar o filter()
função no products
variedade.
1 |
const filteredProducts = products.filter(product => product.rating>=3); |
2 |
console.log(filteredProducts); |
3 |
// output
|
4 |
[
|
5 |
{ id: 1, title: 'Product A', rating: 4 }, |
6 |
{ id: 3, title: 'Product C', rating: 3 }, |
7 |
{ id: 4, title: 'Product D', rating: 5 } |
8 |
]
|
Como você pode ver, o código é curto e facilitará a depuração.
Funções de seta em cadeias de promessas
Ao trabalhar com promessas, as funções de seta são mais curtas, tornando as cadeias de promessas mais legíveis; isso pode ser útil, especialmente durante a depuração.
Uma promessa é um objeto retornado por um método assíncrono. As promessas geralmente são usadas ao trabalhar com APIs e outras tarefas assíncronas que consomem muito tempo.
Considere a Promessa abaixo, que simula um evento assíncrono onde cada .then()
une o array original ao array resultante.
1 |
new Promise(function(resolve) { |
2 |
setTimeout(function() { |
3 |
resolve([]); |
4 |
}, 1000); |
5 |
})
|
6 |
.then(function(result) { |
7 |
return result.concat("Apples"); |
8 |
})
|
9 |
.then(function(result) { |
10 |
return result.concat("Oranges"); |
11 |
})
|
12 |
.then(function(result) { |
13 |
return result.concat("Kiwi"); |
14 |
})
|
15 |
.then(function(result) { |
16 |
console.log(result); |
17 |
});
|
Usando funções de seta, o código é compacto e mais fácil de ler.
1 |
new Promise((resolve) => { |
2 |
setTimeout(() => resolve([]), 1000); |
3 |
})
|
4 |
.then((result) => result.concat("Apples")) |
5 |
.then((result) => result.concat("Oranges")) |
6 |
.then((result) => result.concat("Kiwi")) |
7 |
.then((result) => { |
8 |
console.log(result); |
9 |
});
|
Limitações das funções de seta
Uma das limitações das funções de seta é usá-las como métodos em objetos. Considere o exemplo abaixo, que mostra como calcular o IMC de uma pessoa de acordo com seu peso e altura.
1 |
const personObject = { |
2 |
heightMeters: 1.63, |
3 |
weight: 64, |
4 |
result: () => { |
5 |
const bmi = this.weight / (this.heightMeters * this.heightMeters); |
6 |
|
7 |
console.log(`BMI`, bmi); |
8 |
}
|
9 |
};
|
10 |
const calculateBMI = personObject.result(); |
11 |
|
12 |
console.log(calculateBMI) //output BMI NaN |
O valor de this
dentro da função de seta produzirá o global this
context, que, no meu caso, é a janela em um ambiente de navegador. Não se referirá ao personObject
porque as funções de seta não estabelecem suas próprias this
contexto.
Nesse caso, as funções tradicionais são mais adequadas. Quando usamos uma função tradicional, podemos usar this
para se referir ao PersonObject.
1 |
const personObject = { |
2 |
heightMeters: 1.63, |
3 |
weight: 64, |
4 |
result: function() { |
5 |
const bmi = this.weight / (this.heightMeters * this.heightMeters); |
6 |
console.log(this); |
7 |
//here `this` refers to personObject.
|
8 |
console.log(`BMI`, bmi); |
9 |
}
|
10 |
};
|
11 |
|
12 |
personObject.result(); |
13 |
// {heightMeters: 1.63, weight: 64, result: ƒ}
|
14 |
// BMI 24.088223117166624
|
Outra limitação é que as funções de seta não podem criar novas instâncias de Object. Vejamos o exemplo abaixo, onde tentamos criar um construtor de objeto usando uma função de seta.
1 |
const Student = (name, grade) => { |
2 |
this.name = name; |
3 |
this.grade = grade; |
4 |
}
|
5 |
|
6 |
// Create instance of Student
|
7 |
const student1 = new Student("Mike", 8); |
A saída será:
1 |
Uncaught TypeError: Student is not a constructor |
O erro acima ocorre porque as funções de seta não possuem o prototype
propriedade, que é importante para a instanciação do objeto. Você deve usar funções normais para criar construtores de objetos e usá-los para instanciar objetos.
Aumente o nível do seu JavaScript com Tuts+
Conclusão
As funções de seta são úteis quando queremos uma sintaxe simples e curta. Eles também são perfeitos para funções de expressão única. As funções de seta também são perfeitas ao trabalhar com arrays, retornos de chamada Javascript e promessas. Também é importante observar que as funções das setas podem não ser adequadas para algumas situações. Funções tradicionais são mais adequadas, especialmente quando você precisa de funções nomeadas ou construtoras.