Respostas

Desafios de Funções em JavaScript: Pratique e Domine!

Nível Básico (Questões 1-8)

  1. Uma função é um bloco de código reutilizável projetado para executar uma tarefa específica. Os três principais benefícios são:

    1. Organizar o código: Separam tarefas complexas em partes menores e mais gerenciáveis.

    2. Evitar repetição: Você escreve a lógica uma vez e a chama quantas vezes precisar.

    3. Facilitar a manutenção: Corrigir um bug em uma função corrige o problema em todos os lugares onde ela é usada.

  • Palavra-chave: function (inicia a declaração da função).

  • Nome da função: calcularMedia (o nome que usamos para chamar a função).

  • Parâmetros: nota1 e nota2 (as "variáveis" que a função espera receber).

  • Valor de retorno: (nota1 + nota2) / 2 (o cálculo que a instrução return envia de volta).

  • Parâmetros: São as variáveis listadas na definição da função (ex: nota1, nota2). Eles agem como espaços reservados para os valores que a função receberá.

  • Argumentos: São os valores reais passados para a função quando ela é chamada (ex: calcularMedia(8, 9), onde 8 e 9 são os argumentos).

const despedida = function() {
  // Esta função não tem nome, por isso é anônima.
  // Ela foi atribuída à variável 'despedida'.
  console.log("Até logo!");
};

despedida(); // Chama a função através da variável.
  1. A principal vantagem é a sintaxe mais curta e compacta. Elas permitem escrever funções de forma mais limpa e rápida, especialmente para operações de uma única linha.

  1. Não, uma função não precisa ter return.

  • Com return: A função executa seu código e devolve um valor para quem a chamou. Esse valor pode ser armazenado em uma variável.

  • Sem return: A função apenas executa uma ação (como imprimir algo no console), mas não devolve um valor. O resultado da chamada de uma função sem return é sempre undefined.


Nível Intermediário (Questões 9-18)

  1. A "pilha de chamadas" é um mecanismo que o JavaScript usa para controlar a execução das funções. Cada vez que uma função é chamada, ela é "empilhada" (adicionada ao topo da pilha). Quando a função termina (encontra um return ou o final do seu bloco), ela é "desempilhada" (removida do topo). Isso garante que o fluxo do programa sempre retorne ao ponto correto após a conclusão de uma função.

  2. A declaração tradicional (function nome() {}) sofre hoisting. Isso significa que a declaração da função é "movida" para o topo do seu escopo pelo JavaScript antes da execução do código. Na prática, isso permite que você chame a função antes mesmo de declará-la no código, o que não acontece com expressões de função ou arrow functions.

  3. O resultado será:

  • O primeiro console.log está dentro da função mostrarAnimal, que tem sua própria variável animal ("cachorro") em seu escopo local. Ela usa essa variável.

  • O segundo console.log está fora da função, no escopo global. Ele acessa a variável animal global, cujo valor é "gato".

  1. O nome mais adequado é verificarLogin. Ele segue as convenções de usar um verbo (verificar) para indicar uma ação e camelCase para juntar palavras de forma legível. Nomes como check são genéricos e funcao_de_login usa um padrão diferente (snake_case).

  2. A função retornará undefined. O erro comum é esquecer a palavra-chave return. Embora o cálculo a - b seja feito e armazenado em resultado, a função não devolve esse valor para quem a chamou.

  3. Uma IIFE (Immediately Invoked Function Expression) é uma função que é declarada e executada no mesmo instante. Sua principal utilidade é criar um escopo isolado para evitar que variáveis "vazem" para o escopo global e causem conflitos com outras partes do código.

  • soma(5, 10, 15): O argumento extra (15) é simplesmente ignorado. A função usará apenas os dois primeiros (5 e 10), e o resultado será 15.

  • soma(5): O segundo parâmetro (b) não recebe um argumento, então seu valor se torna undefined. A operação 5 + undefined resulta em NaN (Not a Number).

  1. É uma função que faz pelo menos uma das seguintes coisas:

    1. Recebe uma ou mais funções como argumento (callback).

    2. Retorna uma função como seu resultado. Exemplo: O método .map() de arrays é uma função de ordem superior, pois recebe uma função como argumento para aplicar a cada item.

  2. O valor de resultado será undefined. A função console.log exibe um valor no terminal, mas seu próprio valor de retorno é undefined. Como a função mostrarAlerta retorna o resultado de console.log, ela acaba retornando undefined.


Nível Avançado (Questões 19-30)

  1. Closure é a capacidade de uma função "lembrar" e acessar as variáveis do escopo onde ela foi criada, mesmo que esse escopo já tenha sido encerrado. No exemplo criarContador, a função interna retornada ainda tem acesso à variável contador da função externa criarContador, mesmo após criarContador já ter sido executada.

  2. A função retornará 100. O parâmetro "rest" (...numeros) coleta todos os argumentos passados (10, 20, 30, 40) e os transforma em um array [10, 20, 30, 40]. O método reduce então soma todos os elementos desse array.

  • setTimeout(callback, tempo): Executa a função de callback uma única vez após o tempo especificado.

  • setInterval(callback, tempo): Executa a função de callback repetidamente, a cada tempo especificado, até que seja interrompido (com clearInterval).

  1. Um "callback" é uma função que é passada como argumento para outra função, com a intenção de ser executada mais tarde.

  1. Uma função recursiva é uma função que chama a si mesma dentro de seu próprio corpo. O elemento essencial é a condição de parada (ou caso base). É uma verificação que impede a função de se chamar infinitamente, evitando que a pilha de chamadas estoure (stack overflow).

  2. É desaconselhado por motivos de segurança e performance. Ele avalia o código a partir de uma string, o que é semelhante a usar eval(). Isso pode abrir brechas de segurança (injeção de código) e é mais lento para o motor do JavaScript otimizar do que funções declaradas normalmente.

  3. O objeto arguments é um objeto "parecido com um array" (array-like) que contém todos os argumentos passados para uma função (exceto em arrow functions). O parâmetro "rest" (...) é preferido porque:

    1. Ele cria um array de verdade, permitindo o uso direto de métodos como .map(), .filter(), etc.

    2. É mais explícito e legível, deixando claro que a função pode receber múltiplos argumentos.

  4. Ocorrerá um erro: TypeError: soma is not a function. A declaração da função soma foi sobrescrita pela linha let soma = 10;. No momento em que soma() é chamada, a variável soma contém o número 10, e não uma função, portanto não pode ser invocada com ().

  • Caso 1: Funciona por causa do hoisting. As declarações de função (function nome(){}) são "elevadas" ao topo do escopo, então mostrarMensagem já é conhecida quando é chamada.

  • Caso 2: Gera um ReferenceError. Funções atribuídas a variáveis com const (ou let) não sofrem hoisting. A tentativa de chamar mostrarMensagem2 ocorre antes de sua inicialização, causando o erro.

Atualizado