javascript - riot - ¿Cuál es la diferencia entre la función foo(){} y foo=function(){}?
riot mount (2)
Recibí una excelente explicación al respecto y me hice una pregunta muy similar: dos funciones con el mismo nombre en JavaScript: ¿cómo puede funcionar esto?
Posible duplicado:
JavaScript: var functionName = function () {} vs function functionName () {}
¿son lo mismo? Siempre me he preguntado
No, no son lo mismo, aunque ambos dan como resultado una función a la que se puede llamar a través del símbolo foo
. Una es una declaración de función, la otra es una expresión de función. Se evalúan en diferentes momentos, tienen diferentes efectos en el alcance en el que se definen y son legales en diferentes lugares.
Citando mi respuesta a esta otra pregunta aquí (editada un poco por relevancia), en caso de que alguna vez se eliminara la otra pregunta (y para salvar a las personas que siguen el enlace):
JavaScript tiene dos cosas diferentes pero relacionadas: declaraciones de funciones y expresiones de funciones. Hay marcadas diferencias entre ellos:
Esta es una declaración de función:
function foo() {
// ...
}
Las declaraciones de funciones se evalúan al ingresar en el ámbito de cierre, antes de que se ejecute cualquier código paso a paso. El nombre de la función ( foo
) se agrega al ámbito adjunto (técnicamente, el objeto variable para el contexto de ejecución en el que se define la función).
Esta es una expresión de función (específicamente, una anónima, como su código citado):
var foo = function() {
// ...
};
Las expresiones de función se evalúan como parte del código paso a paso, en el punto en que aparecen (como cualquier otra expresión). Ese crea una función sin nombre, que asigna a la variable foo
.
Las expresiones de función también pueden ser nombradas en lugar de anónimas. Un nombre se ve así:
var x = function foo() { // Valid, but don''t do it; see details below
// ...
};
Una expresión de función nombrada debe ser válida, de acuerdo con la especificación. Debería crear una función con el nombre foo
, pero no poner foo
en el ámbito de encierro, y luego asignar esa función a la variable x
(todo esto ocurre cuando se encuentra la expresión en el código paso a paso). Cuando digo que no debería poner 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 con nombre funcionan en implementaciones compatibles, pero solía haber varios errores en las implementaciones en el mundo salvaje, especialmente en Internet Explorer 8 y versiones anteriores (y algunas versiones anteriores de Safari). IE8 procesa una función nombrada expresada dos veces : primero como una declaración de función (al ingresar al contexto de ejecución), y luego como una expresión de función, generando dos funciones distintas en el proceso. (De Verdad.)
Más aquí: Toma doble y aquí: Desmitificación de expresiones de funciones con nombre
NOTA: Lo siguiente se escribió en 2011. En 2015, las declaraciones de funciones en bloques de control se agregaron al lenguaje como parte de ECMAScript 2015. Su semántica varía dependiendo de si está en modo estricto o suelto, y en modo suelto si el entorno Es un navegador web. Y, por supuesto, si el entorno que está utilizando tiene la compatibilidad correcta con la definición de ES2015 para ellos. (Para mi sorpresa, a partir de este escrito en julio de 2017, Babel tampoco las transpira correctamente). En consecuencia, solo puede usar de manera confiable las declaraciones de funciones dentro de estructuras de control-flujo en situaciones específicas, por lo que probablemente sea la mejor, por ahora , para utilizar expresiones de función en su lugar.
Y finalmente, otra diferencia entre ellos es que son legales. Una expresión de función puede aparecer en cualquier lugar donde puede aparecer una expresión (que está prácticamente en cualquier lugar). Una declaración de función solo puede aparecer en el nivel superior de su ámbito de cierre, fuera de cualquier declaración de flujo de control. Entonces, por ejemplo, esto es válido:
function bar(x) {
var foo;
if (x) {
foo = function() { // Function expression...
// Do X
};
}
else {
foo = function() { // ...and therefore legal
// Do Y
};
}
foo();
}
... pero esto no es, y no hace lo que parece que hace en la mayoría de las implementaciones:
function bar(x) {
if (x) {
function foo() { // Function declaration -- INVALID
// Do X
}
}
else {
function foo() { // INVALID
// Do Y
}
}
foo();
}
Y tiene mucho sentido: dado que las declaraciones de la función foo
se evalúan al ingresar a la función de bar
, antes de que se ejecute cualquier código paso a paso, el intérprete no tiene idea de qué foo
evaluar. Esto no es un problema para las expresiones, ya que se realizan durante el flujo de control.
Como la sintaxis no es válida, las implementaciones son libres de hacer lo que quieran. Nunca he conocido uno que hiciera lo que esperaba, que es lanzar un error de sintaxis y fallar. En su lugar, casi todos ellos simplemente ignoran las declaraciones de flujo de control y hacen lo que deberían hacer si hay dos declaraciones de función foo
en el nivel superior (que es el uso del segundo; eso está en la especificación). Así que solo se usa el segundo foo
. El SpiderMonkey de Firefox es el destacado, parece que (efectivamente) los convierte en expresiones, y por lo tanto, lo que usa depende del valor de x
. Ejemplo vivo .