2010-01-15 16 views
11

Soy nuevo en Javascript y me confundí por el funcionamiento de la declaración de función. Hice algunas pruebas en eso y dieron algunos resultados interesantes:declaración de función ambigua en Javascript

say(); 

function say() 
{ 
    alert("say"); 
} 

El delantero-declaración trabajadas y emergente "decir"

Por el contrario

say(); 

say = function() 
{ 
    alert("say"); 
} 

no funcionó, aunque también declaró un objeto de función

Si declaramos la función y redeclaramos eso después:

function say() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

Recibí "decir" en lugar de "hablar". ¡Eso es sorpresa!

OK. Parece que solo funciona la última declaración de función. A continuación, vamos a declarar objeto de función primero y luego una función de "regular":

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

say(); 

Otra sorpresa, era "hablar" seguido de "hablar". ¡La declaración de la función "normal" no funcionó en absoluto!

¿Hay una explicación de todos ellos? Y, si la declaración de la función "regular" es realmente así de "frágil" y puede anularse fácilmente por el objeto de función con el mismo nombre, ¿debería mantenerme alejado de eso?

Otra pregunta es: con solo el formato de objeto de función, ¿esa declaración directa se vuelve imposible? ¿Hay alguna forma de "simular" eso en Javascript?

Respuesta

0

Puede esperar que las definiciones de sus funciones se apliquen en orden. Entonces todas sus líneas de código que no sean métodos se ejecutarán en orden, incluida la asignación de objetos de función. Esto explica cada uno de tus ejemplos. Sin embargo, es un tema interesante. Realmente no puede asignar un objeto de función después de intentando llamarlo y esperar que funcione. Sin embargo, una definición de función que sigue al código ejecutable se aplicará primero.

3

Javascript funciona así:

El documento se analiza, y los function declaraciones son tomados en cuenta inmediatamente, antes de la ejecución de las instrucciones reales producirse. Esto explica tu primer ejemplo.

Si asigna una función a una variable local, eso se hace durante la ejecución, por lo que no puede usar el método en su segundo ejemplo.

Lo que experimenta es que si declara una función dos veces, la última será utilizada por toda la aplicación. Ese es tu tercer ejemplo.

Estas funciones se hacen miembros del objeto window, de hecho están declaradas globalmente. Si asigna una variable local al valor de una función, esa variable local tendrá prioridad sobre los miembros en el objeto window. Si javascript no puede encontrar una variable local, busca en el alcance para encontrarla, siendo el último recurso el objeto window. Eso es lo que sucedió en su último ejemplo, tiene una variable say que está en un ámbito más específico que la función global say.

Si redeclare say en tiempo de ejecución, es decir, cambiar el orden de las declaraciones en el último ejemplo, entonces se podría ver las dos alertas diferentes que cabría esperar:

say(); //speak, the global function 

function say() { 
    alert('speak'); 
} 

var say = function() { 
    alert('say'); 
} 

say(); //say, the declared local variable 
+0

que ver sus puntos. Pero, ¿cuál es el alcance si defino objetos de funciones locales? Traté de llamar window.say() y el resultado todavía no es lo que esperaba: function say() { alert("say"); } window.say(); popup "decir" y var say = function() { alert("speak"); } window.say(); function say() { alert("say"); } window.say(); popup "hablar" dos veces. ¿Eso significa que tanto la función "global" como el objeto "local" son miembros del objeto ventana? –

+0

lo siento, no sé cómo formatear el comentario ... :( –

+0

@ Xiang: el motivo por el que obtienes "hablar" dos veces es que el intérprete de JavaScript hace dos pasadas: en el primero, crea propiedades del objeto Variable (que se utiliza para buscar variables en el ámbito actual y es el objeto global en código global) para declaraciones 'var' y declaraciones de funciones, y en el segundo pase ejecuta las instrucciones en orden. Lo crucial es que' var' las declaraciones se dividen efectivamente en dos: en el primer pase, se agrega una propiedad con el valor 'undefined' al objeto Variable si aún no contiene una propiedad con ese nombre (continuación ...) –

1
say(); 

function say() 
{ 
    alert("say"); 
} 

Aquí las recuperaciones de intérprete la definición de say() cuando se llama y la ejecuta.

say(); 

say = function() 
{ 
    alert("say"); 
} 

Aquí no existe una definición de say() a buscar - en su lugar va a asignar una función anónima a una variable. El intérprete no puede "encontrar" esto como si pudiera encontrar declaraciones directas.

function say() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

Aquí say se define a continuación, y redefinidos - la última definición gana.

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

say(); 

Aquí say es una variable apuntando a una función anónima (después de la primera declaración se interpreta). Esto tiene prioridad sobre cualquier definición de función, igual que si hubiera colocado la definición de función antes de la asignación.

Pero si tuviera

say(); 

say = function() 
{ 
    alert("speak"); 
} 

say(); 

function say() 
{ 
    alert("say"); 
} 

A continuación, se obtendría "decir" seguido de "hablar".

0

Siempre es una buena idea llamar a la función más tarde, aunque javascript funciona así.

La mayoría de los idiomas no funcionan de esa manera, sino que lo hacen.

function say(){ 
    alert("say"); 
} 

say(); 

o

say = function(){ 
    alert("say"); 
} 

say(); 

o

(function(){ 
    alert("say"); 
})(); 
Cuestiones relacionadas