w3schools una tipos pasar parametros otra llamar funciones funcion desde dentro anonimas javascript function closures strict-mode

tipos - pasar parametros a una funcion javascript desde html



Dos funciones con el mismo nombre en JavaScript: ¿cómo puede funcionar esto? (3)

Por lo que sé, function foo() { aaa(); } function foo() { aaa(); } es solo var foo = function(){ aaa() } en JavaScript. Entonces agregando la function foo() { bbb(); } function foo() { bbb(); } debería sobrescribir la variable foo o ignorar la segunda definición, ese no es el punto. El punto es que debería haber una variable foo .

Entonces, en este ejemplo, la variable me no debería resolverse correctamente desde dentro de los métodos y no está en Explorer 8 :-) . Llegué a este ejemplo tratando de envolverlos en otro cierre donde estaría ( var ) me , pero me sorprendió que no fuera necesario:

var foo = { bar1 : function me() { var index = 1; alert(me); }, bar2 : function me() { var index = 2; alert(me); } }; foo.bar1(); // Shows the first one foo.bar2(); // Shows the second one

Demostración: http://jsfiddle.net/W5dqy/5/


Función AFAIK foo () {aaa (); } es solo var foo = function () {aaa ()} en JavaScript.

Eso es realmente incorrecto. JavaScript tiene dos cosas diferentes pero relacionadas: declaraciones de funciones y expresiones de funciones. Ocurren en diferentes momentos del ciclo de análisis y tienen diferentes efectos.

Esta es una declaración de función:

function foo() { // ... }

Las declaraciones de funciones se procesan al ingresar en el ámbito de cierre, antes de que se ejecute cualquier código paso a paso.

Esta es una expresión de función (específicamente, una anónima):

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

Las expresiones de funciones se procesan como parte del código paso a paso, en el punto en que aparecen (como cualquier otra expresión).

Su código entrecomillado está usando una expresión de función nombrada , que se parece a esto:

var x = function foo() { // ... };

(En su caso, está dentro de un objeto literal, por lo que está en el lado derecho de un : lugar de un = , pero sigue siendo una expresión de función con nombre).

Eso es perfectamente válido, ignorando errores de implementación (más en un momento). Crea una función con el nombre foo , no coloca a foo en el ámbito de encierro y luego asigna esa función a la variable x (todo esto sucede cuando se encuentra la expresión en el código paso a paso). Cuando digo que no pone foo en el ámbito de aplicación, quiero decir exactamente eso:

var x = function foo() { alert(typeof foo); // alerts "function" (in compliant implementations) }; alert(typeof foo); // alerts "undefined" (in compliant implementations)

Observe en qué se diferencia de la forma en que funcionan las declaraciones de funciones (donde el nombre de la función se agrega al ámbito adjunto).

Las expresiones de funciones nombradas funcionan en implementaciones compatibles. Históricamente, hubo errores en las implementaciones (Safari temprano, IE8 y anterior). Las implementaciones modernas las hacen bien, incluyendo IE9 y superiores. (Más aquí: Double take y aquí: Desmitificamos las expresiones de funciones con nombre ).

Por lo tanto, en este ejemplo, la variable me no debe resolverse correctamente desde dentro de los métodos

En realidad, debería ser. El nombre verdadero de una función (el símbolo entre la function y el paréntesis de apertura) siempre está dentro del alcance dentro de la función (ya sea que la función sea de una declaración o una expresión de función nombrada).

NOTA : Lo siguiente se escribió en 2011. Con los avances en JavaScript desde entonces, ya no siento la necesidad de hacer cosas como las siguientes a menos que sepa que voy a estar tratando con IE8 (lo cual es muy raro en estos días).

Debido a errores de implementación, solía evitar expresiones de funciones nombradas. Puedes hacer eso en tu ejemplo simplemente eliminando los nombres de me , pero prefiero las funciones con nombre , y por lo que vale la pena, así es como solía escribir tu objeto:

var foo = (function(){ var publicSymbols = {}; publicSymbols.bar1 = bar1_me; function bar1_me() { var index = 1; alert(bar1_me); } publicSymbols.bar2 = bar2_me; function bar2_me() { var index = 2; alert(bar2_me); } return publicSymbols; })();

(Excepto que probablemente use un nombre más corto que los publicSymbols ).

Así es como se procesa:

  1. Se crea una función anónima adjunta cuando se encuentra la línea var foo = ... en el código paso a paso, y luego se llama (porque tengo el () al final).
  2. Al ingresar al contexto de ejecución creado por esa función anónima, las declaraciones de función bar1_me y bar2_me se procesan y esos símbolos se agregan al ámbito dentro de esa función anónima (técnicamente, al objeto variable para el contexto de ejecución).
  3. El símbolo publicSymbols se agrega al ámbito dentro de la función anónima. (Más: Pobre mal entendido )
  4. El código paso a paso comienza asignando {} a publicSymbols .
  5. El código paso a paso continúa con publicSymbols.bar1 = bar1_me; y publicSymbols.bar2 = bar2_me; , y finalmente return publicSymbols;
  6. El resultado de la función anónima se asigna a foo .

Sin embargo, en estos días, a menos que esté escribiendo el código que conozco debe ser compatible con IE8 (lamentablemente, mientras escribo esto en noviembre de 2015, todavía tiene una cuota de mercado global significativa , pero afortunadamente esa parte está cayendo en picado), no me preocupo por eso . Todos los motores de JavaScript modernos los entienden bien.

También puedes escribir eso así:

var foo = (function(){ return { bar1: bar1_me, bar2: bar2_me }; function bar1_me() { var index = 1; alert(bar1_me); } function bar2_me() { var index = 2; alert(bar2_me); } })();

... ya que son declaraciones de funciones, y por lo tanto son izado. Normalmente no lo hago así, ya que me resulta más fácil hacer el mantenimiento en estructuras grandes si hago la declaración y la asignación de la propiedad una al lado de la otra (o, si no se escribe para IE8, en la misma línea) .


Ambas búsquedas son solo visibles / disponibles dentro de la expresión de función.

De hecho, esas dos se denominan expresiones de función , y la especificación ECMAscript nos dice que el nombre de una expresión no está expuesto al llamado Variable object .

Bueno, intenté poner eso solo en unas pocas palabras, pero al intentar encontrar las palabras correctas, esto termina en una cadena bastante profunda de comportamiento de ECMAscript. Por lo tanto, la function expression no se almacena en un Activation Object / Variable . (Llevaría a la pregunta, quiénes son esos tipos ...).

Corto: cada vez que se llama a una función, se crea un nuevo Context . Hay algún tipo de "magia negra" que se llama Activation object que almacena algunas cosas. Por ejemplo, el

  • argumentos de la función
  • el [[alcance]]
  • cualquier variable creada por var

Por ejemplo:

function foo(test, bar) { var hello = "world"; function visible() { } (function ghost() { }()); }

El objeto de activación para foo se vería así:

  • argumentos: prueba, barra
  • Variables: hola (cadena), visible (función).
  • [[Ámbito]]: (posible función de contexto principal), Objeto global

ghost no se almacena en el AO! Simplemente sería accesible bajo ese nombre dentro de la función en sí. Si bien visible() es una declaración de función (o declaración de función ), se almacena en el AO. Esto se debe a que se evalúa una declaración de función cuando el análisis y la expresión de la función se evalúan en tiempo de ejecución.


Lo que sucede aquí es que la function() tiene muchos significados y usos diferentes.

Cuando yo digo

bar1 : function me() { }

entonces eso es 100% equivalente a

bar1 : function() { }

es decir, el nombre no importa cuando se usa la función para asignar la variable bar1 . En el interior, me asignan, pero tan pronto como queda la definición de la función (cuando asigna bar2 ), me crea de nuevo como una variable local para la definición de la función que se almacena en bar2 .