Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Dúvida na função verifica() e a variável segredos.

Entendi que a variável "segredos" fora da função sorteiaNumeros é diferente da variável com o mesmo nome dentro dela. Porém na função verifica() usamos o laço de repetição for em que usamos a variável segredos para percorrer o array. Como a função "sabe" que estamos percorrendo o "segredos" que está recebendo o retorno da função sorteiaNumeros, já que dentro da função verifica() não declaramos a variável "segredos" ? Ficou confuso mas tentei ser o mais assertivo possível na explicação da dúvida. Obrigado!

function sorteiaNumeros(quantidade) {

        var segredos = [];

        var numero = 1;

        while(numero <= quantidade) {

              var numeroAleatorio = sorteia();
              var achou = false;

              if (numeroAleatorio !== 0) {
                     for(var posicao = 0; posicao < segredos.length; posicao++) {

                           if(segredos[posicao] == numeroAleatorio){
                                achou = true;
                                break;
                           }

                     }

                     if (achou == false) {
                           segredos.push(numeroAleatorio);
                           numero++;
                     }
              }

        }

        return segredos;

    }

    var segredos = sorteiaNumeros(3);

    console.log(segredos);

    var input = document.querySelector("input");
    input.focus();

    function verifica() {

       var achou = false;

       for(var posicao = 0; posicao < segredos.length; posicao++) {

              if(input.value == segredos[posicao]) {

                     alert("Você ACERTOU!");
                     achou = true;
                     break;
              } 
       }

       if(achou == false) {

              alert("Você ERROU!");
       }

       input.value = "";
       input.focus();

    }

    var button = document.querySelector("button");

    button.onclick = verifica;
3 respostas
solução!

A variável segredos que é usada no for está declarada fora de qualquer função, na linha 34 (var segredos = sorteiaNumeros(3);). Pense que o que está dentro de uma função fica restrito ao escopo de dentro da função, o que está fora de uma função fica disponível para ser usado em qualquer função, chamamos de escopo global. Para ficar mais claro, tente mudar o nome da variável da linha 34 e teste. Você recebera o erro Uncaught ReferenceError: segredos is not defined pois não trocou o nome da variável do for, agora altere a variavel segredos do for para o mesmo nome da linha 34 e teste novamente, deve funcionar como antes.

var segredosGlobal = sorteiaNumeros(3);

Não é recomendado criar variáveis com o mesmo nome mesmo em escopos diferentes, justamente para evitar confusões como essa. Sempre que for declarar uma variável de um nome diferente das demais variáveis já declaradas.

Muito obrigado Vinicius! Não sabia muito bem o conceito da variável global, ficou muito mais claro. Surgiu uma outra dúvida, aprendi que o computador interpreta o código linha a linha, no código que eu postei a função verifica() foi escrita acima da variável global segredos, há algum problema nisso em outras linguagens, como problemas de desempenho etc? Obrigado!

Leandro, tem varias perguntas aí, algumas mais avançadas e eu não sou especialista em JS, vou tentar responder. Em linguagens de alto nível, normalmente a gente declara variáveis no começo do código, por questão de organização e legibilidade, mas como você descobriu empiricamente não é obrigatório. Quanto ao desempenho é preciso entender como o interpretador "executa" o seu código. O interpretador JS faz o içamento das variáveis declaradas no seu código. O que é içamento? Quando você declar uma variável com var o interpretado coloca ela no topo do escopo ao qual ela pertence. Ex.:

//um código que você escreveu
function minhaFuncao(){
...
}
var nome = 'vinicius'; 

function outraFuncao(){
...
}

var idade = 28;
//um código que "interpretado"

var nome = 'vinicius'; 
var idade = 28;
function minhaFuncao(){
...
}


function outraFuncao(){
...
}

então independente de onde você chamar uma função que use uma variável o interpretador já "organizou" o seu código.

um código assim funciona em JS normalmente:

console.log(nome);

var nome = 'leandro';

console.log(nome);

//saida: 
//leandro
//leandro

Agora em outras linguagens isso não funciona, você só pode usar uma variável depois que ela foi declarada. Em java por exemplo ocorre um erro de compilação.

public class Teste {

    public static void main(String[] args) {

        System.out.println(nome);

        String nome = "Leandro"; 

        System.out.println(nome);
    }

}

(Exception in thread "main" java.lang.Error: Unresolved compilation problem: nome cannot be resolved to a variable at br.Teste.main(Teste.java:7) )

Em C um erro parecido também acontece.

Agora imagino que você está começando como programador e essas perguntas mais avançadas aparecem, eu aconselho que neste momento você se preocupe mais com um código organizado e bem pensado do que com desempenho.

Para saber mais sobre içamento: https://www.freecodecamp.org/news/what-is-variable-hoisting-differentiating-between-var-let-and-const-in-es6-f1a70bb43d/