programacion - funciones de alto orden javascript
Funciones de orden superior en Javascript (4)
Boolean
es una función. Es la función que está llamando indirectamente a través denoisy
. Un poco confuso, lo sé, porque parece el nombre de un tipo. Pero en JavaScript, esas cosas inicialmente limitadas (Boolean
,Number
,String
, etc.) son funciones . Cuando llama aBoolean
( sin usarnew
), intenta convertir el argumento que le dio en un valor primitivoboolean
y devuelve el resultado. (Ver §15.6.1 en la especificación.)f
es el nombre del argumento en la funciónnoisy
.
Las funciones en JavaScript son objetos de primera clase. Puede pasarlos a otras funciones como argumentos al igual que cualquier otro objeto.
Cuando tu lo hagas
noisy(Boolean)(0)
Hay dos cosas sucediendo. Primero:
// (In effect, we''re not really creating a variable...)
var x = noisy(Boolean);
Eso nos da una función que, cuando se le llama, llamará a Boolean
con el argumento que le damos mientras hacemos esas declaraciones de console.log
. Esta es la función que ve que se crea en noisy
( return function(arg)...
);
Entonces llamamos a esa función:
x(0);
Y ahí es cuando ves la salida de la consola. Como Boolean(0)
es false
, verá que Boolean
devuelve ese valor.
Aquí hay un ejemplo mucho más simple:
function foo(bar) {
bar();
}
function testing() {
alert("testing got called");
}
foo(testing);
Allí, estoy pasando la testing
función a foo
. El nombre del argumento que estoy usando para eso dentro de foo
es bar
. La bar();
línea bar();
llama a la función.
Estoy leyendo Elocuente JavaScript ( la nueva edición ) y llegué a la parte de las funciones de orden superior y estoy confundido sobre lo que está sucediendo en el siguiente código.
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false
¿Por qué la llamada a la función es tan ruidosa? ¿Es (booleano) un reparto? ¿Un reparto para qué? el valor de retorno? o el argumento? por qué no (booleano) ruidoso (0) si es el valor de retorno. O ruidoso ((booleano) 0) si el argumento es el que se está emitiendo.
noisy(Boolean)(0)
¿Qué está pasando en esta línea? ¿Dónde está f () incluso definido?
var val = f(arg);
En caso de que todavía tengas problemas con esto, así es como lo entiendo (también me dolió la cabeza ...)
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0)
Una función es solo un valor regular. La oración anterior es clave para entender lo que está pasando aquí.
Nuestra función ruidosa (f) es un valor. Es lo que devuelve.
noisy (f) devuelve una función que toma un argumento (arg).
ruidoso (f) también toma un argumento (f). Las funciones internas (funciones llamadas desde dentro de funciones) tienen acceso a variables y argumentos que se pasaron a la función externa.
Estamos llamando a nuestra función externa y le pasamos el argumento Boolean. Nuestra función externa devuelve su función interna que toma un argumento (0). Al entender lo anterior, debería quedar claro que ruidoso (Booleano (0)) simplemente pasaría un argumento a nuestra función externa, mientras que no pasaría nada a la función interna que es devuelta por nuestra función externa.
Es tan simple realmente. Ahora que lo entendemos, es difícil creer que nos dio un dolor de cabeza como para comenzar con ... * / `
Soy relativamente nuevo en JS y también acabo de leer a través de Javascript Eloquent y encontré que es más fácil de entender una vez que entendí la llamada de la función (respondiendo a su punto 1):
noisy(Boolean)(0);
El noisy(Boolean)
crea una nueva función y el (0)
lo sigue porque se está pasando como un argumento a esa nueva función. Si te refieres al ejemplo mayor que:
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
También podría llamarse de esta manera:
greaterThan(10)(11);
Espero que eso aclare su primera pregunta sobre por qué se llamó así.
Para la segunda pregunta. La f
en:
var val = f(arg);
es la función Boolean
que se pasó a ser noisy
cuando se ingresó noisy(Boolean)
. Luego se usó como argumento en la función ruidosa. Tampoco me di cuenta de que Boolean podría ser una función en sí misma y no solo un tipo de datos. Como han dicho otros, convierte el argumento que le dio en un valor booleano y devuelve el resultado.
Por lo tanto, val
convierte en Boolean(arg)
que se convierte en Boolean(0)
que se evalúa como false
. Si intentas llamar noisy(Boolean)(1);
Lo verás volver true
. La console.log("called with", arg, "- got", val);
simplemente registra el argumento (0 en este caso) y el resultado de su evaluación (falso).
En efecto, ha cambiado la función booleana en una que registra el argumento y el resultado, y también devuelve el resultado.
Espero que esto ayude. Sólo escribirlo ha ayudado a mi propia comprensión.
Una función sin el () es la función real. Una función con () es una invocación de la función. Además, tenga en cuenta que JavaScript es un lenguaje escrito de forma holgada, por lo que no declara tipos de variables. He añadido algunos comentarios a su ejemplo para intentar ayudar.
// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn''t enforced till the interpreter throws an error.
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
return function(arg) {
console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val.
var val = f(arg);
console.log("called with", arg, "- got", val);
// It now returns val
return val;
};
}
Entonces ruidoso (booleano) (0) funciona así
f es la función booleana
ruidoso devuelve una función como esta
function(arg) {
var val = Boolean(arg);
return val;
}
Así que ahora tenemos
nuestra función devuelta (0)
Que se ejecuta como normal para convertirse
function(0) {
var val = Boolean(0); // false
return val;
}