Estoy atascado con este concepto de 'Funciones que devuelven funciones'. Me refiero al libro "JavaScript orientado a objetos" de Stoyan Stefanov.
Fragmento uno:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b();
}
var s = a();
alert('break');
s();
Salida:
A!
B!
break
Fragmento dos
function a() {
alert('A!');
function b(){
alert('B!');
}
return b;
}
var s = a();
alert('break');
s();
A!
break
B!
¿Alguien puede decirme la diferencia entre regresar b
y b()
en los fragmentos anteriores?
javascript
Cafecorridor
fuente
fuente
Respuestas:
Asignar una variable a una función (sin paréntesis) copia la referencia a la función. Poniendo el paréntesis al final del nombre de una función, llama a la función, devolviendo el valor de retorno de la función.
Manifestación
En su ejemplo, también está definiendo funciones dentro de una función. Como:
La función aún se puede llamar. Todavía existe. Esto se usa en JavaScript todo el tiempo. Las funciones se pueden transferir simplemente como otros valores. Considera lo siguiente:
La función count puede mantener las variables que se definieron fuera de ella. A esto se le llama cierre. También se usa mucho en JavaScript.
fuente
this
solo significa algo dentro de un cuerpo de función, de lo contrario es global. Lo que está diciendothis.sayName
es que desea la variable globalsayName
que no existe, no está definida, por lo que no se puede llamar.Devolver el nombre de la función sin
()
devolver una referencia a la función, que se puede asignar como lo hizo convar s = a()
.s
ahora contiene una referencia a la funciónb()
, y llamars()
es funcionalmente equivalente a llamarb()
.Llamar a la función con
()
una declaración de retorno ejecuta la función y devuelve cualquier valor devuelto por la función. Es similar a llamarvar x = b();
, pero en lugar de asignar el valor deb()
retorno, lo devuelve de la función de llamadaa()
. Si la función enb()
sí no devuelve un valor, la llamada regresaundefined
después de cualquier otro trabajo realizado porb()
.fuente
return b();
llama a la función b () y devuelve su resultado.return b;
devuelve una referencia a la función b, que puede almacenar en una variable para llamar más tarde.fuente
Devolver
b
es devolver un objeto de función. En Javascript, las funciones son solo objetos, como cualquier otro objeto. Si no lo encuentra útil, reemplace la palabra "objeto" por "cosa". Puede devolver cualquier objeto de una función. Puede devolver un valor verdadero / falso. Un número entero (1,2,3,4 ...). Puede devolver una cadena. Puede devolver un objeto complejo con varias propiedades. Y puede devolver una función. una función es solo una cosa.En su caso, devolver
b
devuelve la cosa, la cosa es una función invocable. Devolverb()
devuelve el valor devuelto por la función invocable.Considere este código:
Usando la definición anterior,
return b();
devuelve el valor 42. Por otro lado,return b;
devuelve una función, que en sí misma devuelve el valor de 42. Son dos cosas diferentes.fuente
42
;)Cuando regresa
b
, es solo una referencia a la función b, pero no se está ejecutando en este momento.Cuando regresa
b()
, está ejecutando la función y devolviendo su valor.Trate
alert
ingtypeof(s)
en sus ejemplos. El fragmento b le dará "función". ¿Qué te dará un fragmento?fuente
s
. Intente enreturn this
lugar dereturn b
aunque ... Podrá hacerlos.b()
entonces;)Imagina la función como un tipo, como un int. Puede devolver ints en una función. También puede devolver funciones, son objeto de tipo "función".
Ahora el problema de sintaxis: debido a que las funciones devuelven valores, ¿cómo se puede devolver una función y no su valor de retorno?
omitiendo los corchetes! ¡Porque sin corchetes, la función no se ejecutará! Entonces:
Devolverá la "función" (imagínelo como si estuviera devolviendo un número), mientras que:
Primero ejecuta la función y luego devuelve el valor obtenido al ejecutarla, ¡es una gran diferencia!
fuente
Crea una variable :
Declarar una función :
Alerta el valor de
thing1
(nuestra primera variable):Ahora, si quisiéramos
thing1
ser una referencia a la funciónsomething1
, lo que significa que sería lo mismo que nuestra función creada, haríamos:Sin embargo, si queremos el
return
valor de la función, debemos asignarle el valor de retorno de la función ejecutada. Ejecuta la función usando paréntesis:fuente
Fragmento uno:
la declaración 'b ()' significa ejecutar la función llamada 'b' que muestra un cuadro de diálogo con el texto 'B!'
la declaración 'return b ();' significa ejecutar una función llamada 'b' y luego devolver la función que devuelve 'b'. pero 'b' no devuelve nada, entonces esta declaración 'return b ()' tampoco devuelve nada. Si b () devuelve un número, entonces 'return b ()' también es un número.
Ahora a 's' se le asigna el valor de lo que devuelve 'a ()', que devuelve 'b ()', que no es nada, entonces 's' no es nada (en JavaScript es una cosa en realidad, es un 'indefinido'. cuando le pide a JavaScript que interprete qué tipo de datos es la 's', el intérprete de JavaScript le dirá que 's' es indefinido.) Como 's' es indefinido, cuando le pide a JavaScript que ejecute esta declaración 's ()', le está pidiendo a JavaScript que ejecute una función llamada 's', pero 's' aquí es un 'indefinido', no una función, por lo que JavaScript se quejará, "oye, s no es una función, no sé cómo que ver con este s ", JavaScript mostrará un mensaje de error" Uncaught TypeError: s no es una función "(probado en Firefox y Chrome)
Fragmento dos
ahora, la función 'a' devuelve un puntero / alias a una función llamada 'b'. así que cuando se ejecuta 's = a ()', 's' obtendrá un valor que apunta a b, es decir, 's' es un alias de 'b' ahora, llamar a 's' es igual a llamar a 'b'. es decir, 's' es una función ahora. Ejecutar 's ()' significa ejecutar la función 'b' (lo mismo que ejecutar 'b ()'), un cuadro de diálogo que muestra 'B!' aparecerá (es decir, ejecutando la instrucción 'alert (' B! '); en la función' b ')
fuente
Esto es muy útil en la vida real.
Trabajando con Express.js
Entonces, su
express
ruta regular se ve así:Pero, ¿qué sucede si necesita agregar algún contenedor, controlador de errores o algo?
Luego invocas tu función desde un contenedor.
¿Parece complicado? Bueno, ¿qué tal esto?
Vea al final que está pasando una función que
loggingWrapper
tiene un argumento como otra funciónitWorksHandler
, yloggingWrapper
devuelve una nueva función que tomareq, res, next
como argumentos.fuente