Percursos
/
JavaScript
JavaScript
/
Exercícios
/
Mestre da lasanha
Mestre da lasanha

Mestre da lasanha

Exercício de aprendizagem

Introdução

Uma função é um bloco de código organizado e reutilizável que serve para realizar uma determinada ação. Existem várias formas de definir funções em JavaScript. Aqui vamos ver as declarações de função e as expressões de função. Outras possibilidades, como as funções arrow, serão abordadas noutros conceitos.

Declaração de função

A forma padrão de definir uma função em JavaScript é uma declaração de função, também chamada definição de função ou instrução de função.

É composta pela palavra-chave function, pelo nome da função e por uma lista de parâmetros separados por vírgulas entre parênteses. Segue-se o corpo da função (o conjunto de instruções que define o que a função faz), envolvido em chavetas.

function someName(param1, param2, param3) {
  // ...
}

Em JavaScript, uma função é invocada (chamada) escrevendo o nome da função seguido de parênteses que contêm os argumentos.

someName(arg1, arg2, arg3);

Parâmetros

Quando trabalhas com parâmetros dentro do corpo da função, tem atenção aos possíveis efeitos secundários.

  • Os valores dos tipos de dados primitivos são imutáveis. O valor original nunca é afetado pelo que acontece ao argumento no corpo da função.
  • Em todos os outros valores (objetos, arrays, funções), uma reatribuição não afeta o valor original. No entanto, se modificares um argumento desses (por exemplo, adicionar uma chave a um objeto), isso também modifica o valor original que foi passado.

Por predefinição, todos os parâmetros definidos na declaração da função são opcionais em JavaScript. Se forneceres menos argumentos do que parâmetros, os argumentos em falta serão undefined dentro da função; vê Null and Undefined. Em muitos casos, faz sentido atribuir um valor predefinido mais adequado do que undefined. Isso pode ser feito especificando parâmetros predefinidos diretamente na definição da função.

function someName(param1 = defaultValue1, param2 = defaultValue2) {
  // ...
}

Instrução return

Uma instrução return termina a execução da função e especifica um valor a devolver a quem chamou a função. Uma função pode ter várias instruções return.

function checkNumber(num) {
  if (num === 0) {
    return 'You passed 0, please provide another number.';
  }

  return 'Thanks for passing such a nice number.';
}

O valor devolvido por uma função pode ser guardado numa variável.

function sum(x, y) {
  return x + y;
}

const total = sum(5, 10);
// => 15

O resultado de uma função que não devolve nenhum valor ou que não tem uma instrução return é undefined. Não existem return implícitos em JavaScript.

function nakedReturn(a) {
  a * 2;
  return;
}

nakedReturn(1);
// => undefined

function noReturn(a) {
  a * 2;
}

noReturn(1);
// => undefined

Em JavaScript, só podes devolver exatamente um valor. Se quiseres passar mais informação, tens de a combinar primeiro numa única entidade, normalmente num objeto ou num array.

function divide(a, b) {
  return {
    quotient: Math.floor(a / b),
    remainder: a % b,
  };
}

Expressão de função

Uma declaração de função é uma instrução autónoma. Mas, por vezes, é útil definir uma função como parte de outra expressão, por exemplo, numa atribuição, como parâmetro de uma função (callback) ou como valor num objeto. Isso pode ser feito com uma expressão de função. Tem a mesma sintaxe que uma declaração de função, só que o nome da função pode ser omitido para criar uma função anónima.

const someFunction = function (param) {
  // ...
};

someOtherFunction(function (param) {
  // ...
});

const obj = {
  someFunction: function (param) {
    // ...
  },
};

Instruções

Neste exercício, vais escrever mais algum código relacionado com a preparação e a confeção da tua fantástica lasanha, retirada do teu livro de receitas preferido.

Tens cinco tarefas. A primeira está relacionada com a própria confeção e as outras quatro são sobre a preparação perfeita.

1. Determina se a lasanha está pronta

Quando tens lasanha no forno, queres saber se já a podes tirar ou não. Para garantir que a lasanha não queima no forno, costumas programar um temporizador. Mas às vezes esqueces-te disso.

Escreve uma função cookingStatus que aceita o tempo restante do temporizador, em minutos, como parâmetro. A função tem três resultados possíveis.

  • Se o temporizador mostrar 0, deve devolver 'Lasagna is done.'.
  • Se o temporizador mostrar qualquer outro número, o resultado deve ser 'Not done, please wait.'.
  • Se a função for chamada sem um valor para o temporizador, o resultado deve ser 'You forgot to set the timer.'.

O temporizador nunca vai mostrar um valor abaixo de 0.

cookingStatus(12);
// => 'Not done, please wait.'

cookingStatus();
// => 'You forgot to set the timer.'

2. Estima o tempo de preparação

Para a próxima lasanha que vais preparar, queres garantir que reservas tempo suficiente para poderes desfrutar da confeção. Já fizeste um plano com todas as camadas que a tua lasanha vai ter. Agora queres estimar quanto tempo a preparação vai levar, com base nisso.

Implementa uma função preparationTime que aceita um array de camadas e o tempo médio de preparação por camada, em minutos. A função deve devolver a estimativa do tempo total de preparação, com base no número de camadas. Se a função for chamada sem indicar o tempo médio de preparação, deve assumir-se 2 minutos.

const layers = ['sauce', 'noodles', 'sauce', 'meat', 'mozzarella', 'noodles'];
preparationTime(layers, 3);
// => 18

preparationTime(layers);
// => 12

3. Calcula as quantidades necessárias de massa e molho

Além de reservares o tempo, também queres garantir que tens molho e massa suficientes para cozinhar a lasanha dos teus sonhos. Por cada camada de massa na tua lasanha, vais precisar de 50 gramas de massa. Por cada camada de molho na tua lasanha, vais precisar de 0,2 litros de molho.

Define a função quantities, que recebe um array de camadas como parâmetro. A função vai então determinar a quantidade de massa e de molho necessária para fazer a tua refeição. O resultado deve ser devolvido como um objeto com as chaves noodles e sauce.

quantities(['sauce', 'noodles', 'sauce', 'meat', 'mozzarella', 'noodles']);
// => { noodles: 100, sauce: 0.4 }

4. Adiciona o ingrediente secreto

Há algum tempo, visitaste um amigo e comeste lasanha lá. Estava incrível e tinha algo de especial. O amigo enviou-te a lista de ingredientes e disse-te que o último item da lista é o "ingrediente secreto" que tornou a refeição tão especial. Agora também queres adicionar esse ingrediente secreto à tua receita.

Escreve uma função addSecretIngredient que aceita dois arrays de ingredientes como parâmetros. O primeiro parâmetro é a lista que o teu amigo te enviou e o segundo é a lista de ingredientes da tua própria receita. A função deve adicionar o último item da lista do teu amigo ao fim da tua lista. O array que representa a tua receita deve ser modificado diretamente e a função não deve devolver nada. No entanto, o primeiro argumento não deve ser modificado.

const friendsList = ['noodles', 'sauce', 'mozzarella', 'kampot pepper'];
const myList = ['noodles', 'meat', 'sauce', 'mozzarella'];

addSecretIngredient(friendsList, myList);
// => undefined

console.log(myList);
// => ['noodles', 'meat', 'sauce', 'mozzarella', 'kampot pepper']

5. Escala a receita

As quantidades indicadas no teu livro de receitas só dão para lasanha suficiente para duas porções. Como queres cozinhar para mais pessoas da próxima vez, queres calcular as quantidades para diferentes números de porções.

Implementa uma função scaleRecipe que recebe dois parâmetros.

  • Um objeto de receita que contém as quantidades necessárias para 2 porções. O formato do objeto pode ver-se no exemplo abaixo.
  • O número de porções que queres cozinhar.

A função deve devolver um objeto de receita com as quantidades necessárias para o número desejado de porções. No entanto, queres manter a receita original. Isto significa que, nesta tarefa, o argumento da receita não deve ser modificado.

const recipe = {
  noodles: 200,
  sauce: 0.5,
  mozzarella: 1,
  meat: 100,
};

scaleRecipe(recipe, 4);
// =>
// {
//   noodles: 400,
//   sauce: 1,
//   mozzarella: 2,
//   meat: 200,
// };

console.log(recipe);
// =>
// {
//   noodles: 200,
//   sauce: 0.5,
//   mozzarella: 1,
//   meat: 100,
// };
Editar via GitHub A ligação abre numa nova janela ou separador
JavaScript Exercism

Estás pronto para começar Mestre da lasanha?

Inscreve-te no Exercism para aprenderes e dominares JavaScript com 37 conceitos159 exercícios, e mentoria humana real, tudo grátis.