Funções do Vazio
Existem duas maneiras pelas quais a função fatorial que mencionei acima pode funcionar. Uma possibilidade é que ele possa produzir diretamente a resposta calculada. Nesse caso, não nos dará nada de volta que possamos atribuir a algumas outras variáveis. Ele simplesmente produzirá a resposta. Essas funções que não retornam nada são chamadas de funções void.
Esta é a forma geral de uma função:
function functionName() { statement; statement; etc. }
Este é um exemplo de uma função void:
function greet() { console.log("Hello, World"); }
Para executar a função (também conhecida como chamar a função ou invocar a função), você escreve uma instrução que a chama.
greet();
Eu gostaria de apontar que as funções void realmente retornam undefined
porque retornar algo indica que a função concluiu sua execução.
o ()
é onde passamos a entrada para a função. Quando estamos definindo a função, a entrada é chamada de parâmetro. Quando chamamos a função, a entrada será o valor real e é chamada de argumento. Aqui está um exemplo:
function greet(name) { console.log(`Hello, ${name}`); } // Outputs: Hello, Alberta greet("Alberta");
Com o JavaScript ES6, você pode definir funções usando a sintaxe de seta. Aqui está o nosso greet()
função definida usando a sintaxe de seta:
let greet = () => console.log("Hello, World");
Uma função com um parâmetro:
let greet = name => console.log(`Hello, ${name}`); // Outputs: Hello, Monty greet("Monty");
Uma função com mais de um parâmetro:
let greet = (fname, lname) => console.log(`Hello, ${fname} ${lname}. How are you?`); // Outputs: Hello, Monty Shokeen. How are you? greet("Monty", "Shokeen");
Uma função com várias instruções:
let greet = (fname, lname) => { let name = `${fname} ${lname}`; console.log(`Hello, ${name}`); } // Outputs: Hello, Monty Shokeen greet("Monty", "Shokeen");
Como uma função de seta é uma função anônima, damos um nome à nossa função atribuindo-a a uma variável. Uma das vantagens das funções de seta é que elas podem tornar o código mais compacto.
Se escrevêssemos nossa função fatorial como uma função void, ela poderia se parecer com isto:
function factorial(x) { let result = 1; while(x > 1) { result *= x; x -= 1; } console.log(result); } // Outputs: 3628800 factorial(10); // Outputs: 479001600 factorial(12); // Outputs: 6402373705728000 factorial(18);
Função de retorno de valor
Esse tipo de função retorna um valor. A função deve terminar com uma instrução de retorno. Este exemplo retorna a soma de dois números.
function add(x, y) { return x + y; }
Esta é a forma geral que define uma função de retorno de valor:
function functionName() { statement; statement; //... return expression; }
O valor da expressão é o que obtém a saída da função. Esse tipo de função é útil quando seu valor de retorno é armazenado em uma variável, etc. Basicamente, você deve retornar explicitamente valores de uma função se planeja usar esse valor em algum outro lugar em seu código.
Aqui está nossa função fatorial escrita como uma função de retorno de valor.
function factorial(x) { let result = 1; while(x > 1) { result *= x; x -= 1; } return result; } // Outputs: 3628800 console.log(factorial(10)); // outputs: 479001600 console.log(factorial(12)); // Outputs: 6402373705728000 console.log(factorial(18));
Como você pode ver, obtemos a mesma saída. A única coisa que muda é que usamos um return
para obter nosso valor calculado da função.
Alcance
O escopo de uma variável é a parte do programa onde a variável pode ser acessada. Uma variável pode ser local ou global. O escopo de uma variável local está dentro da função em que foi criada. Nenhum código fora da função pode acessar suas variáveis locais.
Além disso, quando você usa let
ou const
para declarar uma variável, eles têm escopo de bloco. Um bloco é um conjunto de instruções que pertencem juntas como um grupo. Um bloco pode ser tão simples quanto envolver nosso código entre chaves:
{ let a = 2; }
a variável a
é local ao bloco em que está. Um bloco também pode ser um loop ou uma instrução if. Por exemplo:
let a = 1; if (true) { let a = 2; } console.log(a); //1
Porque nossa instrução de console está no mesmo escopo que nossa primeira variável a
, ele exibe esse valor, que é 1. Ele não tem acesso às variáveis dentro do bloco if. Agora, considere este exemplo:
let a = 1; if (true) { let a = 2; console.log(a); //2 }
Agora 2 será exibido porque o escopo das variáveis às quais nossa instrução de console tem acesso está dentro do bloco if. Os parâmetros de uma função também são variáveis locais e só podem ser acessados por código dentro da função. As variáveis globais, por outro lado, podem ser acessadas por todas as instruções no arquivo de um programa. Aqui está um exemplo:
let a = 1; function foo () { a = 2; } console.log(a); //1 foo(); console.log(a); //2
Neste exemplo, a
é uma variável global e temos acesso a ela dentro da função foo. A primeira instrução do console exibirá 1. Depois de chamar foo
o valor de a
é definido como 2, fazendo com que a segunda instrução do console exiba 2.
As variáveis globais devem ser usadas muito pouco e, idealmente, nunca. Como as variáveis globais podem ser acessadas por qualquer parte de um programa, elas correm o risco de serem alteradas de maneiras imprevisíveis. Em um programa grande com milhares de linhas de código, isso torna o programa mais difícil de entender porque você não pode ver facilmente como a variável está sendo usada. É melhor criar e usar variáveis locais.
No entanto, se você precisar usar uma variável em vários lugares em seu programa, não há problema em usar uma constante global. Declarando uma variável com o const
A palavra-chave impede que ela seja alterada, tornando-a mais segura de usar. Você só precisa se preocupar em atualizar o valor da constante no local onde ela foi declarada.
Parâmetros
Lembre-se de que um parâmetro é uma variável que uma função usa para aceitar dados. O parâmetro recebe o valor dos argumentos de uma função quando a função é chamada. A partir do ES6, os parâmetros também podem receber valores padrão com o formato parameterName=value
. Nesse caso, você pode chamar uma função sem argumentos e usará valores padrão. Por exemplo:
function greet (name="World") { console.log(`Hello, ${name}`); } // Outputs: Hello, World greet();
O operador spread/rest é novo no ES6 e pode ser usado para expandir uma matriz ou objeto em valores individuais ou reunir os parâmetros de uma função em uma matriz. Este é um exemplo de uso de um parâmetro rest:
function foo(...args) { console.log(args); } foo( 1, 2, 3, 4, 5); //[1, 2, 3, 4, 5]
Módulos
Suponha que agora você tenha um arquivo com mais de 1.000 linhas. O arquivo está organizado em funções, mas é difícil ver como elas se relacionam.
Para agrupar comportamentos relacionados, devemos colocar nosso código em módulos. Um módulo no ES6 é um arquivo que contém funções e variáveis relacionadas. Os módulos nos permitem ocultar propriedades privadas e expor propriedades públicas que queremos usar em outros arquivos. O nome do arquivo seria o nome do módulo. Os módulos também têm seu próprio escopo. Para usar variáveis fora do escopo do módulo, elas devem ser exportadas. As variáveis que não forem exportadas serão privadas e só poderão ser acessadas dentro do módulo.
Funções e variáveis individuais podem ser exportadas assim:
export function foo() { console.log(“Hello World”); } export let bar = 82; export let baz = [1,2,3];
Como alternativa, várias funções e variáveis podem ser exportadas com uma instrução de exportação:
function foo() { console.log("Hello World"); } let bar = 82; let baz = [1,2,3]; export { foo, bar, baz };
Para usar as variáveis de um módulo, você as importa para o arquivo. Você pode especificar o que deseja importar do módulo assim:
import { foo, bar, baz } from "foo";
Você também pode renomear sua importação:
import { foo as Foo } from "foo"; Foo();
Ou você pode importar todas as propriedades do módulo:
import * as myModule from "foo"; myModule.foo();
Análise
As funções nos permitem dividir nossos programas em programas menores que podemos gerenciar facilmente. Existem dois tipos de funções com base em seus tipos de retorno: funções void e funções que retornam valor. Uma função void retorna undefined
. Uma função de retorno de valor nos devolve um valor.
Escopo é a parte do programa onde uma variável pode ser acessada. As variáveis declaradas dentro de uma função, incluindo os parâmetros da função, são locais. Os blocos também possuem escopo e variáveis locais podem ser criadas dentro deles.
Variáveis não incluídas em um bloco ou módulo serão globais. Se você precisar de uma variável global, é aceitável ter uma constante global. Caso contrário, tente conter seu código em módulos porque os módulos têm seu próprio escopo. Mas ainda melhor, os módulos fornecem estrutura e organização ao seu código.
Este post foi atualizado com contribuições de Monty Shokeen. Monty é um desenvolvedor full-stack que também adora escrever tutoriais e aprender sobre novas bibliotecas JavaScript.