Closures e Invocação Imediata de Função em JavaScript

Como você já sabe, é possível chamar uma função anônima imediatamente e atribuir o resultado a alguma variável:

javascriptlet result = function() {
  return '!';
}();

console.log(result); // exibirá '!'

Frequentemente, a função que é invocada imediatamente é colocada entre parênteses nesses casos, embora não seja necessário. Isso é feito para que fique imediatamente claro que a função está sendo invocada no local:

javascriptlet result = (function() {
  return '!';
})();

console.log(result); // exibirá '!'

Suponha agora que o resultado da função invocada imediatamente seja outra função anônima:

javascriptlet func = (function() {
  return function() {
    console.log('!');
  }
})();

func(); // exibirá '!'

Vamos fazer com que a função retornada armazene a variável num em um closure:

javascriptlet func = (function() {
  let num = 1;
  
  return function() {
    console.log(num);
  }
})();

Se adicionarmos também num++, então a função func se tornará um contador pronto:

javascriptlet func = (function() {
  let num = 1;
  
  return function() {
    console.log(num);
    num++;
  }
})();

func(); // exibirá 1
func(); // exibirá 2
func(); // exibirá 3
func(); // exibirá 4
func(); // exibirá 5
Задание 1

Sem espiar o meu código, implemente independentemente um contador similar.

Задание 2

Modifique o funcionamento do contador para que ele conte até 5 e, em seguida, a contagem recomece do início.