2010-09-17 14 views
66

Los programas de JavaScript consisten en declaraciones y declaraciones de funciones. Cuando se ejecuta un programa de JavaScript, estos dos pasos ocurren:¿Cuántos programas de JavaScript se ejecutan para una sola página web en el navegador?

  1. el código se analiza en busca de declaraciones de funciones, y cada función. la declaración se "ejecuta" (creando un objeto de función) y se crea una referencia con nombre a esa función (para que se pueda llamar a esta función desde una declaración)

  2. las declaraciones se ejecutan (evalúan) secuencialmente (ya que aparecen en el código)

debido a eso, esta funciona bien:

<script> 
    foo(); 
    function foo() { 
     return; 
    } 
</script> 

Aunque la función "foo" se llama antes de que se declara, funciona porque la diversión la declaración de ction se evalúa antes de la declaración.

Sin embargo, esto no funciona :

<script> 
    foo(); 
</script> 
<script> 
    function foo() { 
     return; 
    } 
</script> 

Un ReferenceError será lanzado ("foo no está definido"). Esto lleva a la conclusión de que cada elemento SCRIPT dentro del código HTML de la página web representa un programa JavaScript separado y cada vez que el analizador HTML encuentra un elemento SCRIPT, ejecuta el programa dentro de ese elemento (y luego se ejecuta el programa , el analizador se mueve al código HTML que sigue al elemento SCRIPT).

Por otra parte, este Cómo funciona:

<script> 
    function foo() { 
     return; 
    } 
</script> 
<script> 
    foo(); 
</script> 

Mi entendimiento es que el objeto existe Global (que sirve como objeto variable en el contexto de ejecución global) (y sigue siendo) en todo momento, entonces el primer programa de JavaScript creará el objeto de función y hará una referencia para él, y luego el segundo programa de JavaScript usará esa referencia para llamar a la función. Por lo tanto, todos los programas de JavaScript (dentro de una sola página web) "usan" el mismo objeto Global, y todos los cambios realizados al objeto Global por un programa JavaScript pueden ser observados por todos los programas JavaScript que se ejecutan posteriormente.

Ahora, tenga en cuenta esto ...

<script> 
    // assuming that foo is not defined 
    foo(); 
    alert(1); 
</script> 

En el caso anterior, la llamada de alerta no se ejecute, debido a que el "foo()" declaración arroja una ReferenceError (que rompe todo el programa JavaScript) y por lo tanto, todas las declaraciones posteriores no se ejecutan.

Sin embargo, en este caso ...

<script> 
    // assuming that foo is not defined 
    foo(); 
</script> 
<script> 
    alert(1); 
</script> 

Ahora, la llamada de alerta se alcanza a ejecutar . El primer programa JavaScript arroja un ReferenceError (y como consecuencia se rompe), pero el segundo programa JavaScript se ejecuta normalmente. Por supuesto, el navegador informará el error (aunque sí ejecutó los siguientes programas de JavaScript, después de que ocurriera el error).

Ahora, mis conclusiones son:

  • cada elemento SCRIPT dentro del código HTML de la página web representa un programa JavaScript separado. Estos programas se ejecutan inmediatamente cuando el analizador HTML los encuentra.
  • todos los programas de JavaScript dentro de la misma página web "usan" el mismo objeto Global. Ese objeto global existe en todo momento (desde el momento en que se busca la página web hasta que se destruye la página web). Los programas de JavaScript pueden manipular el objeto Global, y todos los cambios realizados al objeto Global por un programa de JavaScript se pueden observar en todos los programas JavaScript posteriores.
  • si se rompe un programa de JavaScript (al arrojar un error), eso no impide que se ejecuten los siguientes programas de JavaScript.

Compruebe esta publicación y dígame si tengo algún error.

Además, no he encontrado recursos que expliquen los comportamientos mencionados en esta publicación, y supongo que los fabricantes de navegadores deben haber publicado dichos recursos en alguna parte, así que si los conoce, proporcione los enlaces a ellos.

¡ACTUALIZACIÓN!

OK, voy a (intentar) responder a mi propia pregunta aquí :) me dieron una respuesta (por correo electrónico) de Dmitry A. Soshnikov (que tiene un blog acerca de JavaScript en http://www.dmitrysoshnikov.com/).

Su opinión sobre este problema es esta: cada bloque SCRIPT contiene código global. Ejecutar cada bloque SCRIPT crea un nuevo contexto de ejecución. Por lo tanto, cada bloque SCRIPT tiene su propio contexto de ejecución, pero todos esos contextos de ejecución comparten el mismo objeto Global.

Los bloques de SCRIPT se pueden ver como diferentes "subprogramas" con el mismo estado compartido.

Además, la especificación ECMAScript (3ª edición) establece (capítulo 10): "El código global es texto fuente que se trata como un programa ECMAScript".

Respuesta

14

Dmitry Soshnikov ha respondido a su pregunta. Cada elemento <script> se ejecuta como un Programa, tal como lo define la especificación ECMAScript. Hay un objeto global que usa cada programa en una sola página. Y eso es realmente todo.

7

Son programas separados, pero modifican un objeto global compartido.

19

Función de elevación - el proceso que evalúa las declaraciones function antes del resto de la función - es parte del estándar ECMAScript IIRC (No puedo encontrar una referencia ahora, pero recuerdo haber visto discusiones de EMCAScript que lo mencionan). La evaluación de las etiquetas script es parte del estándar HTML. No especifica que sean "programas separados" en muchas palabras, pero sí dice que los elementos del script se evalúan en el orden en que aparecen en el documento. Es por eso que las funciones en las etiquetas de scripts posteriores no se alzan: el script aún no se ha evaluado. Eso también explica por qué una detención de script no corta las secuencias de comandos posteriores: cuando la secuencia de comandos actual deja de evaluar, se inicia la siguiente.

+0

Link explaning HOISTING. http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting – Rajat

4

Otra forma de pensar sobre esto es el ámbito pseudo local vs global. Cada declaración SCRIPT tiene un alcance local para sus métodos/funciones actuales, así como acceso al alcance global actual (previamente declarado).Cada vez que se define un método/función en un bloque SCRIPT, luego se agrega al alcance global y es accesible por los bloques SCRIPT después de él.

Además, aquí es una referencia más lejos de W3C sobre declaración script/manipulación/modificación:

La modificación dinámica de un documento puede modelarse como sigue:

  1. se evaluaron todos los elementos del guión para que el documento se cargue
  2. Se evalúan todas las construcciones de script dentro de un elemento SCRIPT dado que generan SGML CDATA. Su texto generado combinado se inserta en el documento en lugar del elemento SCRIPT .
  3. El CDATA generado se vuelve a evaluar.

This es otro buen recurso en el script/función de evaluación/declaración.

Cuestiones relacionadas