2009-11-10 13 views
14

Espero que alguien me explique por qué el siguiente JavaScript/HTML mostrará "puerta # 2" cuando el HTML se visualiza en un navegador:Hacer referencia a un valor de JavaScript antes de que se declare - ¿Alguien puede explicar esto?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
    <script type="text/javascript"> 
     function testprint() { 
      alert('door #1'); 
     }; 

     window.onload = testprint; 

     function testprint() { 
      alert('door #2'); 
     }; 

     testprint = function() { 
      alert('door #3'); 
     }; 
    </script> 
    <script type="text/javascript"> 
     function testprint() { 
      alert('door #4'); 
     }; 
    </script> 
</head> 
<body> 
</body> 
</html> 

Puesto que sólo la declaración testprint ocurre antes window.onload se establece en testprint, yo esperaría window.onload causa 'puerta # 1' en aparecer. En realidad, onload causa 'puerta # 2'. Tenga en cuenta que hará esto si se incluye o no la primera declaración de testprint.

La tercera y cuarta declaración de testprint utilizar diferentes medios de asignación de la función, he intentado esto para ver si sería anular window.onload 's comportamiento de la misma era la segunda declaración de testprint hace. No lo hizo. Tenga en cuenta que si muevo la cuarta declaración de testprint al final del primer bloque de scripts, se llamaría por window.onload.

Respuesta

38

declaraciones de funciones son objeto de elevación, y son evaluados en tiempo de análisis, por medios de elevación que están a disposición de todo el ámbito de aplicación en donde fueron declarados, por ejemplo:

foo(); // alerts foo 
foo = function() { alert('bar')}; 
function foo() { alert('foo');} 
foo(); // alerts bar 

La primera llamada a foo ejecutará la declaración de la función , porque en tiempo de análisis se puso a disposición, la segunda llamada de foo ejecutará la expresión función, declaró en tiempo de ejecución .

Para obtener una explicación más detallada acerca de las diferencias entre las expresiones de funciones y las declaraciones de funciones, marque this question y this article.

+0

Hay una sutileza para la función de elevación donde [los navegadores no están de acuerdo] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope#Conditionally_defining_a_function). _SpiderMonkey_ ** no ** levantará las funciones declaradas en un alcance condicional, mientras que _V8_ (en el momento de escribir esto) lo hará. –

-1

función testprint es global para la página. testprint = function ... asigna una variable, que no estoy seguro exactamente de todo el alcance de, pero me da la idea de que no se agrega al diccionario de la tabla de funciones como la primera.

0

La razón # 3 no cambia la ventana. La descarga es que las funciones se llaman por referencia, no por nombre. Cuando configura window.onload = testprint, asigna una referencia al valor actual de testprint (puerta n. ° 2, según lo explica CMS) al window.onload. Cambiar el valor testprint más tarde no afecta el valor de window.onload.

La puerta # 4 no anula la puerta n. ° 2 (a menos que, como dijiste, la muevas al primer bloque de scripts) porque está en un bloque de scripts diferente, por lo que se analiza después de que se completa el primer bloque.

Cuestiones relacionadas