Buscar

First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 11 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 1/14
First Class Objects, High-Order
functions, Funções Anônimas e
Closures no JavaScript
Felix Costa
Apr 24, 2017 · 10 min read
As vezes em nossa rotina de estudo nos deparamos com certos termos e conceitos que
não tínhamos visto ou mesmo que não conseguimos assimilar e trazer isso pra nossa
realidade de estudos. Principalmente pra quem segue o modelo autodidata, onde você
não segue a risca um modelo e cronograma por vezes pulamos esses mesmos termos e
conceitos desconhecidos e que são essenciais para avançarmos para o próximo nível.
Dentro do universo JavaScript não é diferente e mesmo tendo ideia de cada um dos
termos que irei apresentar nesse post, já me vi os confundindo ou mesmo os
esquecendo, então vamos entender de maneira direta qual a ligação de cada um deles e
entender de maneira breve o que é cada um.
Devo alerta-lo que esse post não tem o objetivo de esgotar os assuntos relacionados a
cada tópico discutido e sim somente abordar uma introdução simples para entender as
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 2/14
diferenças. No final do artigo deixo várias referências para aí sim estudar e se
aprofundar em cada tópico falado. Esse artigo serve mais para tirar dúvidas entre cada
um dos termos citados.
Pre-Requisitos
O único pre-requisito para você ter total entendimento do texto é já estar um pouco
familiarizado com a sintaxe do JavaScript (Não precisa ser o ES6+), ter uma ideia do
que a Programação Funcional propõem resolver (basicamente conceito mesmo). Caso
algo não seja assimilado, deixe sua dúvida nos comentários ou anote os termos
desconhecidos para sua próxima pesquisa/aventura.
Funções
Funções são velhas conhecidas já e em JavaScript elas seguem a mesma estrutura que
em outras linguagens. Ok, isso sabemos.
Uma função simples em JavaScript que retorna o triplo de um parâmetro qualquer
A função acima é praticamente a mesma se for aplicada em outras linguagens. Porque a
ideia das funções é exatamente essa. Mas há uma coisa que nem todas as linguagens
que dão suporte a funções possuem. E é a nossa primeira letrinha misteriosa.
First Class Objects (Objetos de Primeira Classe)
Em JS e em outras linguagens (principalmente as linguagens funcionais ou que dão
suporte a esse paradigma), funções são valores. Na prática podemos simplesmente
dizer que as funções são um tipo especial de objeto e como qualquer outro objeto nós
podemos trata-lo da mesma forma como tratamos os nossos objetos em JavaScript.
Mesmo o JavaScript não sendo uma linguagem puramente Funcional, podemos tomar
algumas ações que classificam as funções JavaScript como Objetos de Primeira Classe,
view raw
1
2
3
4
5
6
7
simpleFunction.js hosted with ❤ by GitHub
function triple(x) {
 return x * 3;
}
triple(30);
// 90
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 3/14
como por exemplo, jogar uma função para uma variável.
Funções que são Objetos de Primeira Classe podem ser associados a qualquer outro tipo de objeto
Mas como isso é possível? No JavaScript funções são objetos, como mencionei acima.
As funções herdam de um tipo especial chamado Object e podem ser usadas atribuídas
com uma chave contendo um respectivo valor.
Da mesma forma como podemos passar uma função para uma variável, podemos usar
funções dentro de nossos objetos literais e usa-los como métodos de nossos objetos.
view raw
1
2
3
4
5
6
7
8
9
firstClassObject.js hosted with ❤ by GitHub
let triple = function (x) {
 return x * 3;
}
triple(3); // output: 9
let anotherVariable = triple;
anotherVariable(30); // output: 90
view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
warrior.js hosted with ❤ by GitHub
let warrior = {
 hp: 100,
 strength: 20,
 attack: function(target) {
 target.hp -= this.strength;
 }
}
let enemy = {
 hp: 100,
 strength: 12,
 attack: function(target) {
 target.hp -= this.strength;
 }
}
warrior.attack(enemy);
console.log(enemy.hp); // output: 80
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 4/14
Exemplo usado em um artigo do Ryan Christiani demonstrando como usar funções como métodos em
nossos objetos
No exemplo acima, criamos dois objetos simples e cada um deles possui uma função
que está atribuída a uma chave específica do objeto. E podemos executa-la/acessa-la da
mesma forma como acessamos propriedades comuns.
Outra característica que torna o JavaScript como First Class Object é o fato de podemos
passar funções para outras funções como argumentos e até mesmo retornar uma
chamada de função dentro de uma função…. Parece confuso? Calma, vamos usar essas
duas características para partimos para o nosso segundo tópico.
Higher-order Functions (Funções de Ordem Superior) ou
Callbacks
Justamente pelas funções serem First-Class Object, podemos passar uma função como
argumento para outra função e depois executar essa função passada ou até mesmo
retorná-la para ser executada posteriormente.
Uma pequena nota é que as funções de ordem superior também são conhecidas como
Callbacks no JavaScript. Então basicamente a ideia é a mesma com identificações
diferentes.
As Funções de ordem superior ou Funções de Callback são derivadas do paradigma de
programação funcional e ao contrário do muitos imaginam não é necessário ser um
ninja do clã das sombras para entender ou aplicar esses padrões de codificação.
Inclusive você mesmo já deve ter usado / visto e nem sabia que era simplesmente isso.
Passando funções como argumento
Vamos imaginar que precisamos dar um olá para uma pessoa, o nosso famoso Hello
World. Então temos nossa função helloWorld. E vamos imaginar que precisamos
imprimir essa mensagem em várias linguás diferentes então eu preciso que essa função
imprima mensagens em inglês, em francês e etc.
Uma coisa que nossa função precisa é o nome da pessoa a quem queremos
cumprimentar então podemos já afirmar que nossa função recebe um nome como
argumento: helloWorld(name).
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 5/14
Mas como eu poderia resolver o problema das mensagens diferentes de acordo com a
minha escolha sem precisar criar um helloWorldEnglish, HelloWorldPortuguese,
HelloWorldFrancais…?
Nesse exemplo nós temos várias funções, cada uma com um retorno de “ola” diferente.
Como chamar a função helloWorld e ter seu output de acordo com uma língua
específica? Basta eu passar uma função especial para essa finalidade como argumento
e dentro da nossa função principal executar a função que passamos.
Veja que helloWorld recebe dois argumentos: languageFunction e name. Nesse momento
eles podem ser qualquer coisa e apesar de ter o final Function eu somente usei para
deixar claro na assinatura da função que trata-se de uma função mas isso é opcional. E
dentro da nossa função principal, sabendo que languageFunction será uma função e
sabendo que ela tem um objeto de retornar uma string qualquer a depender da lingua,
basta eu concatenar isso com o nosso segundo argumento, que é o nome da pessoa, e
pronto.
A função imprime no nosso console uma mensagem de olá e essa mensagem será
diferente de acordo com a função de língua que passarmos. Seja qual for, se ocomportamento da função for semelhante a esse, será executado.
view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
multipleHelloWorldUsingCallbacks.js hosted with ❤ by GitHub
portugueseHello = function () {
 return "Olá, ";
}
englishHello = function () {
 return "Hello, ";
}
francaisHello = function () {
 return "Bonjour, ";
}
function helloWorld(languageFunction, name) {
 console.log(languageFunction() + name);
}
helloWorld(portugueseHello, "Felix"); // output: Olá, Felix
helloWorld(englishHello, "Felix"); // output: Hello, Felix
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 6/14
Esse é um exemplo pouco prático e foi usado somente para fins didáticos. Nesse
momento começamos a entender que com funções de ordem superior, podemos passar
funções para outras funções e não há limite para isso. Você pode chegar num nível de
encadeamento grande de funções. Claro, esse grande nível traz diversos problemas,
que você pode se aprofundar melhor nas referências sobre Callbacks que eu deixarei no
final. Por fim, mais um exemplo:
Se você já usou ou já viu um código em jQuery então aí está: uma função de ordem superior. A função on()
aceita uma função como argumento e essa função será executada.
Claro que nesse ponto você pode estar se perguntando porque isso seria útil. Um
pequeno spoiler sobre porque isso é útil: composição de funções. Dessa forma podemos
manter nosso código em funções que possuem um objetivo bem definido e construir
funções maiores que utilizam a lógica dessas outras funções. Sem contar que se eu
precisar, em algum lugar do sistema, posso usar as funções de languageFunctions
isoladamente.
Claro, com esse exemplo isso não fica visível, mas a ideia é justamente manter as
funções desacopladas e aí sim, em algum momento do sistema, juntar várias funções
independentes que retornam um super resultado.
Retornando funções dentro de uma função
Esse ponto também pode assustar pela descrição mas não é nada demais. Com o
conceito de funções de ordem superior é possível que o retorno de uma função
principal seja uma função qualquer que foi passada como argumento. Vamos usar o
mesmo exemplo que usamos acima. Observe a leve mudança:
view raw
1
2
3
jqueryCallbacks.js hosted with ❤ by GitHub
$('a').on('click', function() {
 console.log('fui pressionado');
});
1
2
3
4
5
6
7
8
9
portugueseHello = function () {
 return "Olá, ";
}
englishHello = function () {
 return "Hello, ";
}
francaisHello = function () {
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 7/14
A única diferença é que ao invés de executar a função languageFunction dentro da
função helloWorld, nós passamos ela como retorno. O resultado disso é exatamente o
mesmo. Quando chamarmos a função helloWorld, passando os argumentos
necessários, será retornado pra gente o seguinte:
1. O resultado da função que foi passada como argumento, que no caso é
languageFunction
2. A string que representa o nome do cliente.
E isso será apresentado para nós como um return só.
Então recapitulando e resumindo: High-order functions nos permitem, basicamente,
passar funções para funções e retornar funções dentro de outras funções. Essas
características fazem parte do conceito da programação funcional e dentro do
JavaScript são amplamente usadas com objetivo de tornar nosso código mais
declarativo (menos imperativo), baseado em funções (composições), mantendo uma
maior abstração e com uma abordagem funcional, que tem ganhado bastante buzz
ultimamente devido a sua flexibilidade e conceito.
Anonymous Functions (Funções anônimas)
Em todos os nossos exemplos acima, usamos funções que tinham um identificador.
Mesmo as funções que eram associadas a variáveis possuem um identificador que é
exatamente a chave a qual jogados a função. Mas em JavaScript, assim como em outras
linguagens que suportam essa feature, podemos criar funções que não possuem uma
identificação, um nome. Essas são as funções anônimas ou funções sem nome.
view raw
9
10
11
12
13
14
15
16
17
18
19
20
multipleHelloWorldUsingCallbacksAndReturn.js hosted with ❤ by GitHub
francaisHello function () {
 return "Bonjour, ";
}
function helloWorld(languageFunction, name) {
 // return `${languageFunction()} ${name}`; utilizando Template Literals do ES6+
 return languageFunction() + name;
}
helloWorld(portugueseHello, "Felix"); // output: Olá, Felix
helloWorld(englishHello, "Felix"); // output: Hello, Felix
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 8/14
Temos a função result que recebe uma função que tem como objetivo nos apresentar o
triplo de um determinado número. Se fosse com base no que vimos até agora,
criaríamos uma função triple e só passaríamos ela depois, certo? Mas podemos fazer
isso em tempo de execução, como mostra o código entre as linhas 7 e 9.
O JavaScript nos permite adicionar uma definição de função nesse local. Isso é
frequentemente usado em algumas funções nativas ou até mesmo naquele trecho de
código mais acima de jQuery, lembra?
A função on recebe uma função e podemos tanto passar ela de maneira anônima ou
criar ela mais acima e então jogar seu identificador lá. O resultado é o mesmo.
No gist acima eu deixei as duas versões, anonymous e named. O resultado esperado é o
mesmo e a decisão entre escolher um ou outro depende da análise e do objetivo dessa
função. Se há a possibilidade de usa-la em outros contextos do seu código, então
certamente é melhor ter uma identificação para a função. Mas se for algo mais trivial e
view raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
anonymousFunction.js hosted with ❤ by GitHub
//--------------------------------------
// --- ANONYMOUS FUNCTION VERSION --- //
function result (triple) {
 return triple(3);
}
result(function (number) {
 return number * 3;
});
// OUTPUT: 9
//----------------------------------
// --- NAMED FUNCTION VERSION --- //
function tripleNamedFunction (number) {
 return number * 3;
}
result(tripleNamedFunction(3)); // OUTPUT: 9
view raw
1
2
3
jqueryCallbacks.js hosted with ❤ by GitHub
$('a').on('click', function() {
 console.log('fui pressionado');
});
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 9/14
que não é reaproveitado, não há problema em usar a abordagem anônima e cria-la em
tempo de execução.
Importante ressaltar que no JavaScript essas funções também podem ser chamadas de
funções lambda. Então, seja anonymous function ou lambda, o objetivo é somente criar
uma função em tempo de execução e sem uma identificação fixa.
Closures
Esse pode complicar um pouco as coisas, mas vamos focar na objetividade e mostrar
que características tornam um determinado trecho de código em JavaScript como
Closure.
Uma closure é um tipo especial de objeto que combina duas coisas: a função e o
ambiente onde a função foi criada.
Um closure é uma função interior que tem acesso a variáveis de uma função exterior —
cadeia de escopo. O closure tem três cadeias de escopo: ele tem acesso ao seu próprio escopo
(variáveis definidas entre suas chaves), ele tem acesso as variáveis da função exterior e tem
acesso as variáveis globais.
Para entender essa citação, é necessário entenderantes o que são as cadeias de escopo
no JavaScript. Em outro momento escreverei somente sobre essas particularidades do
JavaScript em relação a escopos.
view rawclosure.js hosted with ❤ by GitHub
1
2
3
4
5
6
7
8
9
10
11
12
function showName (firstName, lastName) {
 var nameIntro = "Your name is ";
 //esta função interior tem acesso as variáveis da função exterior, incluindo os parâmet
 function makeFullName () {
 return nameIntro + firstName + " " + lastName;
 }
 return makeFullName ();
}
showName ("Felix", "Costa"); // Your name is Felix Costa
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 10/14
Basicamente temos uma função definida dentro de outra função. A função interna
utiliza e tem ACESSO aos parâmetros e variáveis da função externa.
Em algumas linguagens, o escopo de uma variável é a região onde a variável é
identificada e onde o valor existe. Em muitas linguagens, a definição de um novo
escopo é expressada sempre que há uma ocorrência de chaves {}. Entre essas chaves é
um escopo. Nós temos variáveis globais e que são acessíveis por todo mundo e
podemos ter variáveis que só são conhecidas dentro de uma determinada função e seu
escopo de acesso termina quando a chave se fecha {}.
No JavaScript, essencialmente, antes da versão ES6 (EcmaScript 2015), nós só
tínhamos dois tipos de escopo: global e por função. Ou seja, ou as variáveis são globais,
que são as que são definidas fora de uma função específica, ou são fechadas ao escopo
de uma função e ela só existe e só é acessada dentro daquele escopo. Qualquer outra
função ou até mesmo globalmente não poderíamos usa-la.
Closures (podemos entender como clausura ou função enclausurada) são funções que
“capturam” as variáveis que vêm de fora da função, no caso, das funções externas e
mantem as variáveis vivas mesmo após a função externa ter sido invocada / retornada.
Para usar uma Closure, basta definir uma função dentro de outra função e expor a
mesma. Para expor uma função, devolva-a ou passe-a para outra função. Closures são
comumente usadas para manter privacidade em objetos, por exemplo, métodos
privados. O JavaScript não oferece uma maneira nativa de fazer isso, mas é possível
emular métodos privados usando closures.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let color = "purple"; // escopo global. todo mundo tem acesso a ela
function belt () {
 let color = "blue"; // redefinimos o valor de color somente dentro desse escopo
 
 function myBelt () {
 let color = "brown"; // redefinimos mais uma vez o valor de color para ser usado somente ne
 console.log(color); // brown
 }
 myBelt(); // chamará a função myBelt que imprimirá brown
 console.log(color); // blue
}
belt(); // chamará a função belt que tem seu escopo próprio
console.log(color); // purple, porque é o valor global
04/10/2019 First Class Objects, High-Order functions, Funções Anônimas e Closures no JavaScript
https://medium.com/lfdev-blog/me-explica-96651fc2c105 11/14
Exemplo de como funcionam os escopos e como eles vistos por outros escopos
Então em suma, quando nos referimos a funções dentro de funções e os valores e
escopos a quais cada um dos membros do nosso código tem acesso é quando estamos
falando a respeito de Closures. E nos permitem trabalhar com alguns conceitos
extremamente úteis em nossas aplicações, como encapsulamento de variáveis e
métodos, alteração de escopo, criação de módulos ou até mesmo criar fábricas de
funções (Function Factories). Sua utilização também traz alguns contras e que vão ser
debatidos quando falarmos sobre escopo dentro do JavaScript e suas particularidades
especiais.
Palavras finais
Espero que esse artigo seja útil para você e apesar de não se aprofundar em nenhum
tópico específico espero que ele tenha cumprido com o objetivo que era acabar com as
pesquisas que eu fazia do tipo: anonymous vs callback vs lambda vs whatever in
javascript.
Nos próximos posts relacionados a JavaScript, pretendo abordar a respeito de escopos,
e irmos evoluindo a respeito de alguns temas específicos da linguagem. Qualquer
dúvida, correção ou crítica, peço-lhe que me informe.
Referências
ericdouglas/traduz-ai
traduz-ai - :pencil: Coleção de artigos traduzidos
para pt-br
github.com
ericdouglas/traduz-ai
traduz-ai - :pencil: Coleção de artigos traduzidos
para pt-br
github.com
view rawbelt.js hosted with ❤ by GitHub

Outros materiais