globales closure and javascript scope

closure - JavaScript: ¿En qué se diferencia “function onload(){}” de “onload=function(){}”?



javascript var public (6)

En las respuestas a esta pregunta , leemos que la function f() {} define el nombre localmente, mientras que [var] f = function() {} define globalmente. Eso tiene mucho sentido para mí, pero hay un comportamiento extraño que es diferente entre las dos declaraciones.

Hice una página HTML con el script.

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

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

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

no pasó nada. (Firefox aún 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 tanto window.onload como onload estaban configurados para la función. En ambos casos, el objeto global se establece en la ventana, y no importa cómo escribo la declaración, el objeto de la window está recibiendo la propiedad muy bien.

¿Que está pasando aqui? ¿Por qué una declaración funciona de manera diferente de la otra? ¿Es esta una peculiaridad del lenguaje JavaScript, el DOM o la interacción entre los dos?


Esto es lo que creo que está pasando, basado en los útiles comentarios de Tim Down y una breve discusión con Jonathan Penn:

Cuando el intérprete de JavaScript asigna a la propiedad window.onload , está hablando con un objeto que el navegador le ha dado. El establecedor que invoca notifica que la propiedad se llama onload y, por lo tanto, se apaga al resto del navegador y conecta el evento apropiado. Todo esto está fuera del alcance de JavaScript: la secuencia de comandos solo ve que la propiedad se ha establecido.

Cuando escribe una function onload() {} declaración function onload() {} , el configurador no recibe la llamada de la misma manera. Dado que la declaración hace que ocurra una asignación en el momento del análisis , no del tiempo de evaluación, el intérprete de script sigue adelante y crea la variable sin avisar al navegador; o bien el objeto de la 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 normal del configurador.


Esto genera un error:

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

Esto no hace

foo(); function foo(){}

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


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

function onload() { ... }

.

var onload = function() { ... }

Este fragmento de código asigna una función a una propiedad / variable / campo llamada "onload" en el alcance actual:

onload = function() { ... }

La razón por la que Firefox realizó el enlace y provocó el evento onload en el primer fragmento de código y los otros no pudo ser porque el propio Firefox Chrome (su interfaz de usuario) está escrito y automatizado utilizando JavaScript, por eso es tan flexible y fácil de escribir extensiones en él. De alguna manera, cuando declaró la función onload ámbito local de esa manera, Firefox "reemplazó" la implementación de onload de la window (probablemente el contexto local en ese momento) (en ese momento, una función vacía o indefinida), cuando la otra los navegadores correctamente "aislaron" la declaración en otro ámbito (por ejemplo, global o algo así).


La explicación más simple:

function aaaaaaa(){

Se puede usar antes de que se declare:

aaaaaaa(); function aaaaaaa(){ }

Pero esto no funciona:

aaaaaaa(); aaaaaaa=function(){ }

Esto se debe a que en el tercer código, está asignando aaaaaaa a una función anónima, no declarándola como una función.


Muchas personas están señalando correctamente la diferencia global / local entre ( ACTUALIZACIÓN: esas respuestas han sido eliminadas principalmente por sus autores ahora )

var x = function() {

y

function x() {

Pero eso no responde realmente a tu pregunta específica, ya que no estás haciendo la primera de estas.

La diferencia entre los dos en tu ejemplo es:

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

Mientras

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


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

Lo declarará localmente también.

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