2009-11-30 20 views
20

En las respuestas a this question, leemos que function f() {} define el nombre localmente, mientras que [var] f = function() {} lo define globalmente. Eso tiene mucho sentido para mí, pero hay un comportamiento extraño que es diferente entre las dos declaraciones.JavaScript: ¿En qué se diferencia "function onload() {}" de "onload = function() {}"?

Hice una página HTML con el guión

onload = function() { 
    alert("hello"); 
} 

y funcionó como se esperaba. Cuando lo cambié a

function onload() { 
    alert("hello"); 
} 

no sucedió nada. (Firefox todavía activó el evento, pero WebKit, Opera e Internet Explorer no lo hicieron, aunque francamente no tengo idea de cuál es la correcta)

En ambos casos (en todos los navegadores), pude verificar que ambos window.onload y onload se establecieron en la función. En ambos casos, el objeto global this se establece en la ventana, y no importa cómo escriba la declaración, el objeto window está recibiendo la propiedad muy bien.

¿Qué está pasando aquí? ¿Por qué una declaración funciona de manera diferente a la otra? ¿Es esto una peculiaridad del lenguaje JavaScript, el DOM o la interacción entre los dos?

+1

Estoy empezando a sospechar que este es un error en Webkit/Opera y que Firefox tiene el comportamiento correcto. – Wogan

+0

Ninguno de los dos es correcto per se. El objeto global (al que se refiere 'window') puede tener propiedades definidas por el host (como' onload') y una implementación de ECMAScript 3 es libre de implementar el comportamiento de dicha propiedad como lo considere adecuado, incluido el '[[ ]] 'método que se llama cuando se asigna el valor de la propiedad. –

+0

En Firefox 3.5.5, veo la alerta si uso 'onload = function() {...};' pero no con 'var onload = function() {...};' –

Respuesta

4

Estos dos fragmentos declaran una función en el ámbito actual, llamada "onload". No se realiza ningún enlace.

function onload() { ... } 

.

var onload = function() { ... } 

Este fragmento asigna una función a un/campo de la propiedad/variable denominada "onload" en el ámbito actual:

onload = function() { ... } 

La razón por Firefox lleva a cabo la unión y levantó el proceso de carga en la primera snippet y los demás no podrían ser porque Firefox Chrome (su interfaz de usuario) está escrito y automatizado usando JavaScript, por eso es tan flexible y fácil escribir extensiones en él. De alguna manera, cuando declaraste la función de ámbito local onload de esa manera, Firefox "reemplazó" la implementación de window (muy probablemente el contexto local en ese momento) de onload (en ese momento, una función vacía o indefinida), cuando el otro los navegadores correctamente "sandboxed" la declaración en otro ámbito (por ejemplo, global o algo así).

+0

Buena observación de que Firefox está escrito * en * JavaScript. –

+1

Bueno, no del todo, pero la mayor parte de su cromo (interfaz de usuario) sí lo es. –

0
var onload = function() { 
    alert("hello"); 
} 

Lo declararán localmente también.

sugiero que lea este artículo muy útil: http://kangax.github.io/nfe/

+2

Ese es un gran artículo, pero no responde la pregunta. –

4

Muchas personas están apuntando correctamente a la diferencia/local global entre (ACTUALIZACIÓN: Esas respuestas en su mayoría han sido retirados por sus autores ahora)

var x = function() { 

y

function x() { 

Pero eso no responde a su realidad pregunta específica ya que en realidad no estás haciendo el primero de estos.

La diferencia entre los dos en el ejemplo es:

// Adds a function to the onload event 
onload = function() { 
    alert("hello"); 
} 

Mientras

// Declares a new function called "onload" 
function onload() { 
    alert("hello"); 
} 
+0

Tal vez es porque este último se evalúa en el tiempo de análisis, por lo que el objeto 'ventana' todavía no está listo para aceptar eventos. –

+0

Declarar una función llamada "onload" no lo vincula explícitamente al evento onload, por lo que aún tendría que indicarle a los navegadores que activen la función "onload" cuando se active el evento "onload" (aunque algunos pueden suponer que lo hacen) . – Fenton

+0

¿De verdad? Asignar una función a 'window.onload' funciona bien en mi experiencia. –

1

Esto es lo que creo que está pasando, sobre la base de votos comentarios de Tim abajo y una breve discusión con Jonathan Penn :

Cuando el intérprete de JavaScript se asigna a la propiedad window.onload, está hablando con un objeto que el navegador le ha proporcionado. El organismo que invoca se da cuenta de que la propiedad se llama onload, por lo que se dirige al resto del navegador y conecta el evento apropiado. Todo esto está fuera del alcance de JavaScript: el script solo ve que la propiedad se ha configurado.

Cuando se escribe una declaración function onload() {}, el colocador no se llama de la misma manera.Dado que la declaración hace que una asignación ocurra en parse tiempo, no en tiempo de evaluación, el intérprete de guiones sigue adelante y crea la variable sin indicarle al navegador; o si no, el objeto ventana no está listo para recibir eventos. Sea lo que sea, el navegador no tiene la oportunidad de ver la asignación como lo hace cuando escribe onload = function() {}, que pasa por la rutina de establecimiento normal.

-1

Esto genera un error:

foo(); 
var foo = function(){}; 

Esto no es así:

foo(); 
function foo(){} 

La segunda sintaxis es por lo tanto más agradable cuando se está utilizando funciones de modularizar y organizar su código, mientras que la primera la sintaxis es más agradable para el paradigma de las funciones como datos.

+0

Esta es una respuesta a [var functionName = function() {} vs function functionName() {}] (http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname); no responde * esta * pregunta, que trata de enlaces de eventos en 'ventana'. – apsillers

0

La explicación más simple:

function aaaaaaa(){ 

Puede ser utilizado antes de que se declarated:

aaaaaaa(); 
function aaaaaaa(){ 

} 

Pero esto no funciona:

aaaaaaa(); 
aaaaaaa=function(){ 

} 

Eso es porque en el tercer código , estás asignando aaaaaaa a una función anónima, no declarando como una función.

Cuestiones relacionadas