Anteriormente, exploramos o princípio de funcionamento do JavaScript a partir do mecanismo de análise do mecanismo JavaScript. Agora usamos um exemplo mais vívido para ilustrar a ordem de execução do código JavaScript na página. Se o mecanismo de funcionamento do mecanismo JavaScript é relativamente profundo porque pertence ao comportamento subjacente, então a ordem de execução do código JavaScript é mais vívida, porque podemos sentir intuitivamente essa ordem de execução. é mais complicado, então também é necessário criar um perfil da linguagem JavaScript antes de mergulhar nela.
1.1 Execute o código JavaScript na ordem do fluxo do documento HTML
Em primeiro lugar, os leitores devem saber que o processo de análise de documentos HTML no navegador é o seguinte: o navegador analisa gradualmente a estrutura da página e as informações de cima para baixo de acordo com o fluxo do documento. O código JavaScript como um script incorporado também deve ser contado como um componente do documento HTML, portanto, a ordem de execução do código JavaScript durante o carregamento também é determinada com base na ordem em que a tag de script <script> aparece. Por exemplo, navegue na página de documentação abaixo e você verá que o código é analisado passo a passo, de cima para baixo.
Copie o código do código da seguinte forma:
<roteiro>
alert("Script principal");
</script>
<html><head>
<roteiro>
alerta("script principal");
</script>
<título></título>
</head>
<corpo>
<roteiro>
alerta("script da página");
</script>
</body></html>
<roteiro>
alerta("script inferior");
</script>
Se um script de arquivo JavaScript externo for importado através do atributo src da tag de script <script>, então ele também será executado na ordem em que suas instruções aparecem, e o processo de execução faz parte do carregamento do documento. A execução não será atrasada porque se trata de um arquivo JavaScript externo. Por exemplo, mova os scripts nas áreas de cabeçalho e corpo do documento acima para arquivos JavaScript externos e importe-os por meio do atributo src. Continuando a visualizar o documento da página, você verá a mesma ordem de execução.
Copie o código do código da seguinte forma:
<roteiro>
alert("Script principal");
</script>
<html>
<cabeça>
<script src="//www.VeVB.COm/head.js"></script>
<título></título>
</head>
<corpo>
<script src="//www.VeVB.COm/body.js"></script>
</body>
</html>
<roteiro>
alerta("script inferior");
</script>
1.2 A relação entre pré-compilação e ordem de execução
Em Javascript, função é o primeiro tipo de Javascript. Quando escrevemos uma função, estamos apenas criando uma entidade do tipo função.
Assim como podemos escrevê-lo desta forma:
Copie o código do código da seguinte forma:
funçãoOlá()
{
alerta("Olá");
}
Olá();
varOlá = função()
{
alerta("Olá");
}
Olá();
Na verdade, eles são todos iguais. Mas quando modificamos as funções, encontraremos problemas muito estranhos.
Copie o código do código da seguinte forma:
<scripttype="texto/javascript">
functionOlá() {
alerta("Olá");
}
Olá();
functionOlá() {
alerta("Olá mundo");
}
Olá();
</script>
Veremos o resultado assim: Hello World é exibido duas vezes seguidas.
Em vez do Hello e Hello World que imaginamos.
Isso ocorre porque o Javascript não é completamente interpretado e executado em ordem. Em vez disso, o Javascript é "pré-compilado" antes da interpretação, as funções definidas serão executadas primeiro e todas as variáveis var serão criadas, o valor padrão é indefinido para melhorar. eficiência de execução do programa.
Em outras palavras, o trecho de código acima é, na verdade, pré-compilado pelo mecanismo JS neste formato:
Copie o código do código da seguinte forma:
<scripttype="texto/javascript">
varOlá = function() {
alerta("Olá");
}
Olá = função() {
alerta("Olá mundo");
}
Olá();
Olá();
</script>
Podemos ver claramente no código acima que as funções também são dados e variáveis. Também podemos atribuir (reatribuir) valores às "funções".
Claro, para evitar esta situação, também podemos fazer o seguinte:
Copie o código do código da seguinte forma:
<scripttype="texto/javascript">
functionOlá() {
alerta("Olá");
}
Olá();
</script>
<scripttype="texto/javascript">
functionOlá() {
alerta("Olá mundo");
}
Olá();
</script>
Desta forma, o programa é dividido em duas seções, e o motor JS não irá juntá-las.
Quando o mecanismo JavaScript analisa um script, ele processa todas as variáveis e funções declaradas durante a pré-compilação.
Faça o seguinte:
1. Antes da execução, será realizada uma operação semelhante à "pré-compilação": primeiro, será criado um objeto ativo no ambiente de execução atual, e essas variáveis declaradas com var serão definidas como atributos do objeto ativo, mas neste momento , a atribuição dessas variáveis será indefinida, e as funções definidas com function também serão adicionadas como propriedades do objeto ativo, e seus valores serão exatamente a definição da função.
2. Durante a fase de interpretação e execução, quando uma variável precisar ser analisada, ela será primeiro pesquisada no objeto ativo do ambiente de execução atual. Caso não seja encontrada e o proprietário do ambiente de execução possua o atributo protótipo, ele. será pesquisado na cadeia de protótipos, caso contrário, será pesquisado de acordo com a cadeia de escopo. Ao encontrar uma instrução como var a = ..., será atribuído um valor à variável correspondente (nota: a atribuição da variável é concluída durante a fase de interpretação e execução. Se a variável for usada antes disso, seu valor será indefinido). Portanto, apenas parecerá que nenhum erro será relatado quando o interpretador JavaScript executar o seguinte script:
Copie o código do código da seguinte forma:
alert(a); // valor de retorno indefinido
var a =1;
alerta(a); // retorna valor 1
Como as declarações de variáveis são processadas no momento da pré-compilação, elas ficam visíveis para todo o código durante a execução. No entanto, você também verá que ao executar o código acima, o valor solicitado é indefinido, e não 1. Isso ocorre porque o processo de inicialização da variável ocorre durante a execução, não na pré-compilação. Durante a execução, o interpretador JavaScript analisa o código em ordem. Se não for atribuído um valor a uma variável na linha de código anterior, o interpretador JavaScript usará o valor padrão indefinido. Como a variável a recebe um valor na segunda linha, a terceira linha de código solicitará que o valor da variável a seja 1, não indefinido.
Da mesma forma, no exemplo a seguir, é legal chamar a função antes que ela seja declarada e possa ser analisada corretamente, portanto, o valor de retorno é 1.
Copie o código do código da seguinte forma:
f(); // Chama a função, retorna valor 1
função f(){
alerta(1);
}
No entanto, se a função for definida da seguinte maneira, o interpretador JavaScript solicitará um erro de sintaxe.
Copie o código do código da seguinte forma:
f(); // Chama a função e retorna erro de sintaxe
varf = função(){
alerta(1);
}
Isso ocorre porque a função definida no exemplo acima é atribuída apenas à variável f como um valor. Portanto, durante o período de pré-compilação, o interpretador JavaScript só pode processar a declaração da variável f, e o valor da variável f só pode. ser pressionado durante o período de execução. Se as atribuições forem executadas sequencialmente, ocorrerá naturalmente um erro de sintaxe, indicando que o objeto f não pode ser encontrado.
Adeus alguns exemplos:
Copie o código do código da seguinte forma:
<script type="texto/javascript">
/*Durante o processo de pré-compilação, func é um atributo no objeto ativo no ambiente de janela, e o valor é uma função, cobrindo o valor indefinido*/
alerta(func); //função func(){alert("olá!")}
var func = "isto é uma variável"
função função(){
alerta("olá!")
}
/*Durante a execução, var foi encontrado e reatribuído para "isto é uma variável"*/
alerta(func); //esta é uma variável
</script>
Copie o código do código da seguinte forma:
<script type="texto/javascript">
var nome = "feng";
{
/*Primeiro, atribua um nome a indefinido no ambiente func e, em seguida, procure o atributo name do objeto ativo no ambiente func durante a execução. Neste momento, o valor foi pré-compilado para indefinido, portanto a saída é indefinida, não. feng */
alerta(nome); //nome var indefinido = "JSF";
alerta(nome); //JSF
}
função();
alerta(nome);
//feng
</script>
Embora as declarações de variáveis e funções possam estar em qualquer lugar do documento, é uma boa prática declarar variáveis e funções globais antes de todo o código JavaScript e inicializar e atribuir variáveis. Dentro de uma função, as variáveis são declaradas primeiro e depois referenciadas.
1.3 Execute código JavaScript em blocos
Os chamados blocos de código são segmentos de código separados por tags <script>. Por exemplo, as duas tags <script> abaixo representam dois blocos de código JavaScript.
Copie o código do código da seguinte forma:
<roteiro>
//bloco de código JavaScript 1
var a =1;
</script>
<roteiro>
//bloco de código JavaScript 2
função f(){
alerta(1);
}
</script>
Quando o interpretador JavaScript executa um script, ele o executa em blocos. Em termos leigos, se o navegador encontrar uma tag <script> ao analisar o fluxo de documentos HTML, o interpretador JavaScript aguardará até que o bloco de código seja carregado, primeiro pré-compile o bloco de código e depois execute-o. Após a execução, o navegador continua a analisar o fluxo de documentos HTML abaixo e o interpretador JavaScript está pronto para processar o próximo bloco de código.
Como o JavaScript é executado em blocos, se você chamar uma variável ou função declarada em um bloco subsequente em um bloco JavaScript, um erro de sintaxe será solicitado. Por exemplo, quando o interpretador JavaScript executa o código a seguir, ele exibirá um erro de sintaxe, mostrando que a variável a é indefinida e o objeto f não pode ser encontrado.
Copie o código do código da seguinte forma:
<roteiro>
//bloco de código JavaScript 1
alerta(a);
f();
</script>
<roteiro>
//bloco de código JavaScript 2
var a =1;
função f(){
alerta(1);
}
</script>
Embora o JavaScript seja executado em blocos, blocos diferentes pertencem ao mesmo escopo global, o que significa que variáveis e funções entre blocos podem ser compartilhadas.
1.4 Use o mecanismo de evento para alterar a ordem de execução do JavaScript
Como o JavaScript processa o código em partes e segue a ordem de análise do fluxo do documento HTML, você verá esses erros de sintaxe no exemplo acima. Mas quando o fluxo de documentos é carregado, tal erro não ocorrerá se for acessado novamente. Por exemplo, se o código que acessa as variáveis e funções no segundo bloco de código for colocado na função de evento de inicialização da página, não haverá erros de sintaxe.
Copie o código do código da seguinte forma:
<roteiro>
//bloco de código JavaScript 1
window.onload = function(){ // Função de tratamento de eventos de inicialização de página
alerta(a);
f();
}
</script>
<roteiro>
//bloco de código JavaScript 2
var a =1;
função f(){
alerta(1);
}
</script>
Por motivos de segurança, geralmente só permitimos a execução de código JavaScript após a inicialização da página. Isso pode evitar o impacto da velocidade da rede na execução do JavaScript e também evitar as restrições na execução do JavaScript causadas pelo fluxo de documentos HTML.
Perceber
Se houver vários manipuladores de eventos windows.onload em uma página, apenas o último será válido. Para resolver esse problema, você pode colocar todos os scripts ou funções de chamada no mesmo manipulador de eventos onload, por exemplo:
Copie o código do código da seguinte forma:
janela.onload=função(){
f1();
f2();
f3();
}
E desta forma, a ordem de execução das funções pode ser alterada simplesmente ajustando a ordem de chamada das funções no manipulador de eventos onload.
Além dos eventos de inicialização da página, também podemos alterar a ordem de execução do código JavaScript por meio de vários eventos interativos, como eventos de mouse, eventos de teclado, gatilhos de relógio, etc. Para obter explicações detalhadas, consulte o Capítulo 14.
1.5 Ordem de execução de scripts de saída JavaScript
No desenvolvimento de JavaScript, o método write() do objeto de documento é frequentemente usado para gerar scripts JavaScript. Então, como esses scripts de saída dinâmica são executados? Por exemplo:
Copie o código do código da seguinte forma:
document.write('<script type="text/javascript">');
document.write('f();');
document.write('função f(){');
document.write('alert(1);');
documento.write('}');
document.write('</script>');
Executando o código acima, descobriremos que: o método document.write() primeiro grava a string do script de saída no local do documento onde o script está localizado. o navegador continua a analisar o conteúdo de saída document.write () e, em seguida, analisa os documentos HTML subsequentes em ordem. Em outras palavras, a sequência de código gerada pelo script JavaScript será executada imediatamente após a saída.
Observe que a saída da string de script JavaScript usando o método document.write() deve ser colocada na tag <script> que é gerada ao mesmo tempo, caso contrário, o intérprete JavaScript não será capaz de reconhecer esses códigos JavaScript legais e será exibido como uma string comum no documento da página. Por exemplo, o código a seguir exibirá o código JavaScript em vez de executá-lo.
Copie o código do código da seguinte forma:
document.write('f();');
document.write('função f(){');
document.write('alert(1);');
document.write(');');
No entanto, existem certos riscos na saída e execução de scripts por meio do método document.write(), porque diferentes mecanismos JavaScript os executam em ordens diferentes e podem ocorrer bugs em navegadores diferentes durante a análise.
Ø Problema 1: As variáveis ou funções declaradas no arquivo JavaScript externo importado através do método document.write() não podem ser encontradas. Por exemplo, observe o código de exemplo abaixo.
Copie o código do código da seguinte forma:
document.write('<script type="text/javascript" src="//www.VeVB.COm/test.js">
</script>');
document.write('<script type="text/javascript">');
document.write('alert(n);'); // IE avisa que a variável n não pode ser encontrada
document.write('</script>');
alert(n+1); // Todos os navegadores avisarão que a variável n não pode ser encontrada
O código do arquivo JavaScript externo (test.js) é o seguinte:
Copie o código do código da seguinte forma:
var n = 1;
Quando testado em navegadores diferentes, você encontrará um erro de sintaxe e a variável n não pode ser encontrada. Em outras palavras, se você acessar em um bloco de código JavaScript as variáveis contidas no arquivo JavaScript externo importado na saída do script usando o método document.write() neste bloco de código, um erro de sintaxe será exibido. Ao mesmo tempo, se estiver no navegador IE, não apenas no script, mas também no script de saída, ele solicitará que a variável de saída importada para o arquivo JavaScript externo não possa ser encontrada (a expressão é um pouco longa e complicada, leitores que não entendem podem tentar executar o código acima para serem entendidos).
Ø Pergunta 2: Diferentes mecanismos JavaScript têm ordens de execução ligeiramente diferentes para scripts de importação externos de saída. Por exemplo, observe o código de exemplo abaixo.
Copie o código do código da seguinte forma:
<script type="texto/javascript">
document.write('<script type="text/javascript" src="http://shaozhuqing.com/test1.js">
</script>');
document.write('<script type="text/javascript">');
documento.write('alert(2);')
document.write('alert(n+2);');
document.write('</script>');
</script>
<script type="texto/javascript">
alerta(n+3);
</script>
O código do arquivo JavaScript externo (test1.js) é mostrado abaixo.
Copie o código do código da seguinte forma:
var n = 1;
alerta(n);
A sequência de execução no navegador IE é mostrada na Figura 1-6.
Figura 1-6 A sequência de execução e erros de sintaxe solicitados pelo navegador IE 7
A sequência de execução em navegadores que atendem aos padrões DOM é diferente daquela dos navegadores IE e não há erros de sintaxe. A Figura 1.7 mostra a sequência de execução no navegador Firefox 3.0.
Figura 1-7 Sequência de execução do navegador Firefox 3 e erros de sintaxe solicitados
Resolva as diferentes ordens de execução de diferentes navegadores e possíveis bugs. Podemos colocar todos os arquivos externos importados usando o script de saída em blocos de código independentes, para que este problema possa ser evitado de acordo com a ordem de execução dos blocos de código JavaScript apresentados acima. Por exemplo, para o exemplo acima, você pode projetá-lo assim:
Copie o código do código da seguinte forma:
<script type="texto/javascript">
document.write('<script type="text/javascript" src="//www.VeVB.COm/test1.js"></script>');
</script>
<script type="texto/javascript">
document.write('<script type="text/javascript">');
document.write('alert(2);') ; // Dica 2
document.write('alert(n+2);'); // Dica 3
document.write('</script>');
alerta(n+3); //Dica 4
</script>
<script type="texto/javascript">
alerta(n+4); //Dica 5
</script>
Desta forma, o código acima pode ser executado em ordem em diferentes navegadores, e a ordem de saída é 1, 2, 3, 4 e 5. A razão do problema é: uma contradição entre o script importado de saída e o bloco de código JavaScript atual. Se a saída for separada, não haverá conflito.