javascript - significado - ¿Qué significa cuando una variable es igual a una función?
pasar variables entre funciones javascript (5)
Posible duplicado:
JavaScript: var functionName = function () {} vs function functionName () {}
En JavaScript, ¿cuál es el propósito de definir una variable como una función? He visto esta convención antes y no la entiendo completamente.
Por ejemplo, en algún punto de un script, una función se llama así:
whatever();
Pero donde esperaría ver una función llamada como whatever
, como esta:
function whatever(){
}
En su lugar, veré una variable llamada como se define como una función, como esta:
var whatever = function(){
}
¿Cuál es el propósito de esto? ¿Por qué harías esto en lugar de simplemente nombrar la función?
Cuando asigna una función a una variable, puede pasarla como un argumento a otras funciones y también extenderla para hacer uso del modelo de objetos de Javascript.
Las funciones en JavaScript son objetos; son valores , en otras palabras. Por lo tanto, siempre puede establecer una variable para referirse a una función independientemente de cómo se define la función:
function foo() { ... }
var anotherFoo = foo;
anotherFoo(); // calls foo
Las funciones son valores que se pueden usar como propiedades de objeto, parámetros de función, elementos de matriz y cualquier otra cosa que un valor general pueda hacer en JavaScript. Son objetos y pueden tener sus propias propiedades también.
Si declara una variable de función, usando "var", dentro de una función, solo se puede acceder a la variable dentro de esa función. Al salir de la función, la variable se destruye. Estas variables se llaman variables locales. Puede tener variables locales con el mismo nombre en diferentes funciones, ya que cada una es reconocida solo por la función en la que se declara.
esto es para que pueda almacenar funciones en variables y, por ejemplo, pasarlas a otras funciones como parámetros. Un ejemplo en el que esto es útil es al escribir funciones asíncronas a las que se pasan devoluciones de llamada como argumentos
var callback = function() { console.log(''done'', result)}
var dosomething = function(callback) {
//do some stuff here
...
result = 1;
callback(result);
}
Como las funciones son objetos en javascript, también puede ampliarlas con propiedades y métodos.
Nota : consulte la actualización al final de la respuesta, las declaraciones dentro de los bloques se hicieron válidas (pero bastante complicadas si no está usando el modo estricto).
Aquí hay una razón:
var whatever;
if (some_condition) {
whatever = function() {
// Do something
};
}
else {
whatever = function() {
// Do something else
};
}
whatever();
Es posible que vea un código así en la inicialización de una biblioteca que tiene que manejar las diferencias de implementación (como las diferencias entre los navegadores web, attachEvent de IE del IE frente al addEventListener
estándar). No se puede hacer el equivalente con una declaración de función:
if (some_condition) {
function whatever() { // <=== DON''T DO THIS
// Do something
}
}
else {
function whatever() { // <=== IT''S INVALID
// Do something else
}
}
whatever();
... no están especificados dentro de las estructuras de control, por lo que los motores de JavaScript pueden hacer lo que quieren, y diferentes motores han hecho cosas diferentes. (Editar: De nuevo, vea la nota a continuación, están especificados ahora).
Por separado, hay una gran diferencia entre
var whatever = function() {
// ...
};
y
function whatever() {
// ...
}
La primera es una expresión de función , y se evalúa cuando el código alcanza ese punto en la ejecución paso a paso del contexto (por ejemplo, la función en la que se encuentra o la ejecución paso a paso del código global). También da como resultado una función anónima (la variable que se refiere a ella tiene un nombre, pero la función no, lo que tiene implicaciones para que sus herramientas lo ayuden ).
La segunda es una declaración de función , y se evalúa al ingresar al contexto, antes de que se ejecute cualquier código paso a paso. (Algunos llaman a esto "elevación" porque algo más abajo en la fuente ocurre antes que algo más arriba en la fuente). La función también recibe un nombre propio.
Así que considera:
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "function"
function bar() {
}
}
mientras
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "undefined"
var bar = function() {
};
}
En el primer ejemplo, con la declaración, la declaración se procesa antes de que se ejecute doSomething
y otro código por pasos. En el segundo ejemplo, debido a que es una expresión , se ejecuta como parte del código paso a paso y, por lo tanto, la función no se define arriba (la variable se define arriba, porque var
también se "eleva" ).
Y terminando: por el momento, no puede hacer esto en general en la web del lado del cliente:
var bar = function foo() { // <=== Don''t do this in client-side code for now
// ...
};
Debería poder hacer eso, se llama expresión de función con nombre y es una expresión de función que le da a la función un nombre propio. Pero varios motores de JavaScript en varias ocasiones se han equivocado, e IE continuó muy equivocado hasta hace muy poco .
Actualización para ES2015 +
A partir de ES2015 (también conocido como "ES6"), las declaraciones de funciones dentro de los bloques se agregaron a la especificación.
Modo estricto
En modo estricto, el comportamiento recién especificado es simple y fácil de entender: tienen el alcance del bloque en el que ocurren y se elevan a la parte superior.
Así que esto:
"use strict";
if (Math.random() < 0.5) {
foo();
function foo() {
console.log("low");
}
} else {
foo();
function foo() {
console.log("high");
}
}
console.log(typeof foo); // undefined
(Observe cómo las llamadas a las funciones están por encima de las funciones dentro de los bloques).
... es esencialmente equivalente a esto:
"use strict";
if (Math.random() < 0.5) {
let foo = function() {
console.log("low");
};
foo();
} else {
let foo = function() {
console.log("high");
};
foo();
}
console.log(typeof foo); // undefined
Modo suelto
El comportamiento del modo suelto es mucho más complejo y, además, en teoría varía entre los motores de JavaScript en los navegadores web y los motores de JavaScript no en los navegadores web. No voy a entrar aquí. Simplemente no lo hagas. Si insiste en declaraciones de funciones dentro de bloques, use el modo estricto, donde tengan sentido y sean consistentes en todos los entornos.