Percursos
/
JavaScript
JavaScript
/
Exercícios
/
Parque de diversões
Parque de diversões

Parque de diversões

Exercício de aprendizagem

Introdução

Ao contrário de muitas outras linguagens, existem em JavaScript duas entidades diferentes que representam a ausência de um valor (com significado). São null e undefined.

Null

O valor primitivo null é usado como um "valor vazio" intencional para variáveis de qualquer tipo.

let name = null;
// name is intentionally set to "empty" because it is not
// available

Podes verificar se uma variável é null com o operador de igualdade estrita ===.

let name = null;

name === null;
// => true

Undefined

Uma variável à qual não foi atribuído um valor é do tipo undefined.1

Isto significa que, enquanto null representa um valor vazio (mas ainda um valor), undefined representa a ausência total de um valor. 🤯

O undefined aparece em contextos diferentes.

  • Se uma variável é declarada sem um valor (inicialização), é undefined.
  • Se tentares aceder ao valor de uma chave inexistente num objeto, obténs undefined.
  • Se uma função não devolve um valor, o resultado é undefined.
  • Se um argumento não é passado a uma função, é undefined, a não ser que esse argumento tenha um valor predefinido.
let name;
console.log(name);
// => undefined

Podes verificar se uma variável é undefined com o operador de igualdade estrita ===.

let name;

name === undefined;
// => true

Encadeamento opcional

Se tentares obter um valor aninhado num objeto, mas a chave principal não existir, o JavaScript lança um erro. Para evitar isto facilmente, o encadeamento opcional foi adicionado à especificação da linguagem em 2020. Com o operador de encadeamento opcional ?., podes garantir que o JavaScript só tenta aceder à chave aninhada se a chave principal não for null nem undefined. Caso contrário, é devolvido undefined.

const obj = {
  address: {
    street: 'Trincomalee Highway',
    city: 'Batticaloa',
  },
};

obj.address.zipCode;
// => undefined

obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined

obj.residence?.street;
// => undefined

Coalescência nula

Há situações em que queres aplicar um valor predefinido caso uma variável seja null ou undefined (mas só nesse caso). Para resolver isto, o operador de coalescência nula ?? foi introduzido em 2020. Devolve o operando do lado direito apenas quando o operando do lado esquerdo é null ou undefined. Caso contrário, é devolvido o operando do lado esquerdo.

let amount = null;
amount = amount ?? 1;
// => 1

amount = 0;
amount = amount ?? 1;
// => 0

[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (consultado a 4 de junho de 2021).

Instruções

O teu trabalho é fornecer e manter partes do sistema informático de um parque de diversões. Em particular, és responsável pelo programa que gere os visitantes e os bilhetes.

Primeiro, vais criar um novo visitante no sistema. Depois, vais criar uma função para revogar um bilhete. Nas tarefas 3 e 4, vais trabalhar no sistema de rastreio de bilhetes que ajuda a prevenir falsificações. Por fim, vais ajudar a adaptar o sistema a novos requisitos legais.

1. Criar um novo visitante

Quando os visitantes chegam ao parque de diversões pela primeira vez, têm de se registar, introduzindo o nome e a idade num terminal e aceitando os termos e condições. Claro que também têm de comprar um bilhete. Cada bilhete tem um identificador como H32AZ123.

Escreve uma função createVisitor que aceita três argumentos.

  • O nome do visitante.
  • A idade do visitante.
  • O identificador do bilhete que o visitante comprou.

A função deve devolver um objeto que contém esta informação. As chaves do objeto devem chamar-se name, age e ticketId.

createVisitor('Verena Nardi', 45, 'H32AZ123');
// => { name: 'Verena Nardi', age: 45, ticketId: 'H32AZ123' }

2. Revogar o bilhete

Quando as pessoas saem do parque de diversões, o bilhete é revogado. Se voltarem, têm de comprar um novo. Para poupar algum tempo aos visitantes habituais, só precisam de se registar uma vez e a informação do visitante fica guardada para as visitas seguintes.

Isto significa que, quando um visitante sai do parque, só o bilhete deve ser invalidado, mas o resto do objeto do visitante deve manter-se igual. Implementa a função revokeTicket, que aceita um objeto visitante, define o identificador do bilhete como null e devolve o objeto no final.

const visitor = {
  name: 'Verena Nardi',
  age: 45,
  ticketId: 'H32AZ123',
};

revokeTicket(visitor);
// => { name: 'Verena Nardi', age: 45, ticketId: null }

3. Determinar o estado do bilhete

Para prevenir falsificações, os identificadores dos bilhetes são únicos. Assim que um bilhete é impresso, o seu identificador é adicionado como chave num objeto do sistema, para que possa ser rastreado.

Antes de o bilhete ser vendido a um visitante, é guardado com o valor null no objeto de rastreio de bilhetes. Quando é vendido a um visitante, o nome do visitante é atribuído como valor. Quando os funcionários têm dúvidas sobre a validade de um bilhete, precisam de verificar o estado do bilhete no sistema.

Implementa uma função ticketStatus que aceita o objeto de rastreio e um identificador de bilhete como argumentos. Deve devolver um dos seguintes resultados.

  • 'unknown ticket id' se o identificador não for encontrado no objeto de rastreio
  • 'not sold' caso o bilhete tenha sido impresso mas não vendido
  • 'sold to {name}' em que {name} é o nome do visitante, se o bilhete foi vendido
const tickets = {
  '0H2AZ123': null,
  '23LA9T41': 'Verena Nardi',
};

ticketStatus(tickets, 'RE90VAW7');
// => 'unknown ticket id'

ticketStatus(tickets, '0H2AZ123');
// => 'not sold'

ticketStatus(tickets, '23LA9T41');
// => 'sold to Verena Nardi'

4. Melhorar a resposta do estado do bilhete

Passado algum tempo, recebes comentários dos funcionários a dizer que querem que o estado do bilhete seja mais fácil de perceber à primeira vista. Só querem ver o nome do visitante ou então que o bilhete é inválido.

Escreve uma função simpleTicketStatus que aceita os mesmos argumentos que ticketStatus na tarefa 3. Esta função devolve apenas um de dois resultados possíveis.

  • o nome do visitante, se o bilhete foi vendido
  • 'invalid ticket !!!' se o bilhete ainda não foi vendido ou se o identificador não foi encontrado no objeto de rastreio
const tickets = {
  '0H2AZ123': null,
  '23LA9T41': 'Verena Nardi',
};

simpleTicketStatus(tickets, '23LA9T41');
// => 'Verena Nardi'

simpleTicketStatus(tickets, '0H2AZ123');
// => 'invalid ticket !!!'

simpleTicketStatus(tickets, 'RE90VAW7');
// => 'invalid ticket !!!'

5. Determinar a versão dos termos e condições

Devido a novos requisitos legais, os objetos de visitante criados recentemente contêm agora também informação detalhada sobre os "Termos e Condições Gerais" (GTC) que o utilizador aceitou. Podes ver abaixo um exemplo do novo objeto de visitante.

Os caixas do parque de diversões precisam agora de verificar se um visitante tem de assinar uma nova versão dos GTC. Para isso, implementa uma função gtcVersion que aceita um objeto visitante como argumento e devolve a versão dos GTC, se estiver disponível. Se a informação sobre a versão não estiver disponível, não deve ser devolvido nada.

const visitorNew = {
  name: 'Verena Nardi',
  age: 45,
  ticketId: 'H32AZ123',
  gtc: {
    signed: true,
    version: '2.1',
  },
};

gtcVersion(visitorNew);
// => '2.1'

const visitorOld = {
  name: 'Verena Nardi',
  age: 45,
  ticketId: 'H32AZ123',
};

gtcVersion(visitorOld);
// => undefined
Editar via GitHub A ligação abre numa nova janela ou separador
JavaScript Exercism

Estás pronto para começar Parque de diversões?

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