Executando verificação de segurança...
3

[Dúvida] todo o código dentro do escopo de uma função?

Fala pessoal, tenho uma dúvida sobre programas reais. sou iniciante e já fui introduzido ao conceito incial de função no javascript e me deparei com um conceito novo que é enolver todo o código do programa em uma única função e no fim chamar ela, eu entendi todo o motivo de fazer isso, mas me questionei e agora pergunto a vocês: essa é uma ideia utilizada em projetos reais? projetos reais são introduzidos em uma função principal? não sei se minha pergunta faz sentido, peço desculpas se não fizer, mas preciso de ajuda.

exemplo de código:

function meuPrograma(){
    const listaComObjetos = [];
    const nome = document.querySelector('.nome');
    const idade = document.querySelector('.idade');
    const peso = document.querySelector('.peso');
    const altura = document.querySelector('.altura');
    const form = document.querySelector('.form');
    const botao = document.querySelector('.botao');
    const resultado = document.querySelector('.resultado');
    
    function criaObjeto(nome,idade,peso,altura){
        return{
            nome:nome,
            peso:peso,
            idade:idade,
            altura:altura
        }
    };
    
    function recebeFormulario(e){
        e.preventDefault();

        let objeto = criaObjeto(nome.value,idade.value,peso.value,altura.value);
        listaComObjetos.push(objeto);
        console.log(listaComObjetos);
        
        resultado.innerHTML += `Nome: ${nome.value}, idade: ${idade.value}, peso: ${peso.value}, altura: ${altura.value} </br>`
    }

    form.addEventListener('submit', recebeFormulario)
}

meuPrograma()
Carregando publicação patrocinada...
3

A resposta para a sua pergunta (e que costuma ser a mesma para a maioria das situações) é: "Depende".

No caso, este código usa querySelector para buscar vários elementos da página. Mas o que acontece se o script rodar antes da página carregar, ou seja, quando os elementos ainda não estiverem disponíveis?

Por exemplo, se estiver assim:

<html>
  <head>
    <script type="text/javascript">
      function meuPrograma() {
        const nome = document.querySelector('.nome');
        alert('Nome: ' + nome.value);
      }
      meuPrograma();
    </script>
  </head>
  <body>
    <input type="text" class="nome" value="Fulano">
  </body>
</html>

Neste caso dará erro, porque ele tenta buscar por um elemento que ainda não existe (o script roda antes do HTML referente ao input ser carregado). E mesmo se não usarmos a função, continuará dando erro:

<html>
  <head>
    <script type="text/javascript">
      const nome = document.querySelector('.nome');
      alert('Nome: ' + nome.value);
    </script>
  </head>
  <body>
    <input type="text" class="nome" value="Fulano">
  </body>
</html>

Em vez disso, eu poderia fazer assim:

<script type="text/javascript">
function meuPrograma() {
    const nome = document.querySelector('.nome');
    alert('Nome: ' + nome.value);
}
document.addEventListener('DOMContentLoaded', meuPrograma);
</script>

No caso, o evento DOMContentLoaded só chamará a função quando o HTML for completamente carregado.

É claro que eu poderia fazer assim também:

<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
    const nome = document.querySelector('.nome');
    alert('Nome: ' + nome.value);
});
</script>

Ou seja, uso uma função anônima e coloco tudo que preciso lá dentro.


Mas suponha que a função está em um arquivo .js próprio. Então no HTML eu poderia fazer:

<html>
  <head>
    <script type="text/javascript" src="arquivo_que_tem_a_funcao.js"></script>
    <script type="text/javascript">
        document.addEventListener('DOMContentLoaded', meuPrograma);
    </script>
  </head>
  <body>
    <input type="text" class="nome" value="Fulano">
  </body>
</html>

Ou seja, separo a definição da função do seu uso, e assim fica mais organizado (pode ser que outro arquivo precise da função em outras circunstâncias, por exemplo, ao clicar em um botão, etc).

Enfim, colocar tudo em uma única função é algo que pode fazer sentido, dependendo do caso. Mas tem vezes que pode ser um exagero, por exemplo, se for algo que precise rodar imediatamente e não vai ser reusado em lugar nenhum, aí talvez não justifique.

1
2

Olá jonaspy, eu entendi sua pergunta...

Olha, dizer que é certo ou errado nesse caso pode depender um pouco... Mas falando de dia a dia, normalmente, quando vc estiver trabalhando em uma aplicação web por exemplo, utilizando um framework por exemplo, vc vai separar seu código em pequenas funções ou arquivos... pode ser que esse framework, no final das contas, por baixo dos panos, esteja executando todo aquele código em uma função como no seu exemplo acima... mas você utilizando o framework, vai estar criando arquivos separados, importando eles em algum lugar e sim... pode ser que tudo que vc criou no final das contas rode em uma função...

Esse seu exemplo acima, n está errado por exemplo.... vc criou uma função com diversas outras funções dentro dela ( n estou falando do que o código em si faz, mas respondendo especificamente sua pergunta )... isso q vc faz n é errado!

1

Dentro do contexto de JS não é algo necessário, mas pode ser usado em determinados casos como outros comentários já apontaram.

Em outras linguagens, é obrigatório estar dentro uma função chamada main, como em C

int main(void) {
    // snip
}

mas também existem linguagens interpretadas que não precisam de uma função sinalizando o ponto de entrada, porém é uma boa prática usar, como python

def main():
    // snip


if __name__ == "__main__":
    main()
1

pensei nessa perspectiva olhando pra outras linguagens tbm, pq ja reparei que em muitas se inicia com uma função, por isso me perguntei se no javascript esse também era um modelo adotado. ainda sou bem iniciante, por isso quando me bati de frente com isso fiquei bem confuso. obrigado pelo feedback amigo.

1

Não faz sentido

Não tem sentido em fazer isso. Quando você abre o site, o o programa já é executado sincronamente(linha por linha).

Fazer isso só está adicionando uma função completamente desnecessária e alocando memória também desnecessária. Além disso, ao trabalhar com this que é algo mais complexo na frente, você irá ter problemas com escopo, pois ao invés do this acessar o escopo global, ele vai acessar o da função.

Resumindo: Desnecessário essa prática, pois não faz sentido chamar todo o script com uma função sendo que no momento em que abrimos o site, isso já acontece. É apenas mémoria alocada desnecessariamente.

Bugs:

A quantidade de bugs que isso pode causar... para não ter dores de cabeça com isso, utilize função apenas quando necessário, que não é o caso desta função que praticamente isola seu código do escopo global.

Parabéns:

Parabéns por perguntar antes de adotar está pratica. Questione tudo, não tenha vergonha. Estamos aqui para aprender. Todo mundo já foi iniciante um dia e todo mundo já teve o seu momento Hello World.

1

Na verdade faz sentido sim e é uma prática muito comum.
Assim como vc disse, realmente todo o código é executado no momento em que a página é renderizada, mas da forma como vc disse dá a entender que por esse motivo então não há nenhuma forma de o usuário alterar esse código ou o comportamento dele, mas não é bem assim.
O código realmente não é possível de ser alterado, pelo menos não com facilidade, mas os valores das variáveis sim, e alterando os valores das variáveis o usuário pode mudar o comportamento do código e aí o ceu é o limite.

Geralmente é muito comum vc ver o pessoal usando pelo menos uma função anônimima autoexecutada, pq dessa forma não é possível alterar os valores das variáveis pelo console do navegador:

(function(){
  // todo o código vai aqui
})();

ainda mais comum é alguns programadores usarem um event listener pra que essa função seja executada apenas depois que o carregamento da página seja concluído

2

Bom, aparentemente o meu comentário foi bem, como eu posso dizer, estreito. Deveria ter olhado para a questão com a mente mais aberta e pensar em possíveis possibilidades.

Agradeço o comentário, clearou bastante minha mente.

4

Muito interessante como pessoas experientes aceitam que não são os donos da verdade e observam o ponto de vista das outras. Em outros lugares isso teria se tornado uma discussão sem sentido.

1

Geralmente eu uso uma função anônima pra fazer isso, ficaria mais ou menos assim:

(function(){
    const listaComObjetos = [];
    const nome = document.querySelector('.nome');
    const idade = document.querySelector('.idade');
    const peso = document.querySelector('.peso');
    const altura = document.querySelector('.altura');
    const form = document.querySelector('.form');
    const botao = document.querySelector('.botao');
    const resultado = document.querySelector('.resultado');
    
    function criaObjeto(nome,idade,peso,altura){
        return{
            nome:nome,
            peso:peso,
            idade:idade,
            altura:altura
        }
    };
    
    function recebeFormulario(e){
        e.preventDefault();

        let objeto = criaObjeto(nome.value,idade.value,peso.value,altura.value);
        listaComObjetos.push(objeto);
        console.log(listaComObjetos);
        
        resultado.innerHTML += `Nome: ${nome.value}, idade: ${idade.value}, peso: ${peso.value}, altura: ${altura.value} </br>`
    }

    form.addEventListener('submit', recebeFormulario)
})();

Quando vc define tudo de forma global, as variaveis no escopo global são acessíveis e possíveis de terem os valores alterados pelo console do navegador, as funções também são possíveis de serem executadas pelo console, por isso eu faço dessa forma.
Alguém comentou aqui sobre colocar um event listener pra que seja executado quando o carregamento da página for concluído, isso também é uma boa prática mas nem sempre vai ser necessário, geralmente só colocar o JS no final do body, exatamente antes de fechar a tag body () já vai ser suficiente pra que o js seja executado depois da renderização dos componentes HTML, a não ser que tenha algo atrazando a renderização.

Prefiro usar essa função anônima pq as funções que são definidas de forma global também podem ser executadas pelo console do navegador, é só digitar o nome, passar os parametros da forma que quiser e apertar enter que vai ser executado, mas se a função for anonima, isso garante que não tem como ela ser executada a não ser no carregamento da página, pois nada faz referencia a ela, e tudo que está dentro da função anônima só é acessível pela própria função.

Só um adendo: já usei isso pra pegar dados de um serviço grande, empresa famosa, que era pago e tinha um acesso limitado, aí quando chegava no limite só poderia ter acesso no dia seguinte, aí abri o console, mudei algumas variáveis e comecei a executar as funções e aí consegui ter acesso ilimitado (não vou falar a empresa pra não dar problema), depois o pessoal descobriu a falha e corrigiram.

1

Esse modelo de função eu ainda não conhecia, ela é definida e chamada automaticamente, é isso ? sobre utilizar funções pra envolver o escopo do programa, posso utilizar até mesmo como uma medida de seguranca para não deixar os códigos do sistema global ne ?

3

Aquele finalzinho alí ();

"chama a função"

javascript é meio maluco mesmo (e eu adoro)

Pra vc entender melhor:

Isso:

function meuPrograna(){
 📄
}

é igual a isso:

(function(){📄})();

Agora, se vc quer ver como seria um "programa" real, em node seria mais ou menos isso:

onst express = require('express')
const app = express();

//
// Biliotecas
//
require('./libs/cors')(app)
require('./libs/bodyParser')(app)
require('./libs/knex')(app)
require('./libs/auth')(app)
require('./libs/errors')(app)

//
// API
//
require('./api/hello')(app)
require('./api/usuarios')(app)

//
// start
//
require('./libs/start')(app)
1

faz sentido, mano. e sim, javascript é meio louco kskss mas to curtindo muito, mas ainda tô meio perdido e é muito massa ter um feedback desses como o seu. obrigado mesmo, maninho

2

Exatamente, a função é definida e executada logo em seguida automaticamente.

Todos os frameworks js que conheço geram o js final dessa forma, dentro dessa função anônima auto executada.

Pra entender melhor são dois parenteses ()(), dentro do primeiro vai a função anonima e o segundo faz com que a função dentro do primeiro seja executada (function(){})().

Quanto a segurança, sim, faz sentido pensar por esse lado também, mas sempre aliado com outras práticas