¿Qué significa cuando una variable es igual a una función? [duplicar]


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 momento de un script, una función se llama así:

whatever();

Pero donde esperaría ver una función llamada whatever, como esto:

function whatever(){

}

En su lugar voy a ver una variable llamada whatever que se define como una función, así:

var whatever = function(){

}

¿Cuál es el propósito de esto? ¿Por qué harías esto en lugar de solo nombrar la función?

Author: Community, 2012-02-27

5 answers

Nota : Por favor vea la actualización al final de la respuesta, las declaraciones dentro de bloques se volvieron 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 código como ese en la inicialización de una biblioteca que tiene que manejar las diferencias de implementación (como las diferencias entre navegadores web, a'la IE attachEvent vs.el estándar addEventListener). No se puede hacer el equivalente con una función declaració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 JavaScript pueden hacer lo que quieran, y diferentes motores han hecho cosas diferentes. (Edit: De nuevo, vea la nota a continuación, se especifican 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 de la contexto (por ejemplo, la función en la que está, o la ejecución paso a paso del código global). También resulta en 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 ayudar a sus herramientas a ayudarlo ).

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 " ho " porque algo más abajo en la fuente ocurre antes que algo más alto en la fuente.) La función también recibe un nombre propio.

Así que considere:

function foo() {
    doSomething();
    doSomethingElse();
    console.log("typeof bar = " + typeof bar); // Logs "function"

    function bar() {
    }
}

Considerando que

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 el doSomething y se ejecuta otro código paso a paso. 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 arriba, porque var también está "izada" ).

Y terminando: Por el momento, no se puede hacer esto en general cosas web del lado del cliente:

var bar = function foo() { // <=== Don't do this in client-side code for now
    // ...
};

Usted deberíaser capaz de hacer eso, se llama expresión de función llamada y es una expresión de función que le da a la función un nombre propio. Pero varios motores JavaScript en varias ocasiones se han equivocado, y IE continuó equivocándose hasta muy recientemente.


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: se circunscriben al bloque en el que ocurren, y se elevan a la parte superior del mismo.

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 son por encima de el funciones dentro de los bloques.)

Essentially 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 de modo suelto es mucho más complejo y, además, en teoría, varía entre los motores JavaScript en los navegadores web y los motores JavaScript no en los navegadores web. No voy a entrar aquí. No lo hagas. Si insiste en declaraciones de funciones dentro de bloques, utilice el modo estricto, donde tienen sentido y son consistentes a lo largo ambiente.

 32
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-28 11:42:00

Esto es para que pueda almacenar funciones en variables y, por ejemplo, pasarlas a otras funciones como parámetros. Un ejemplo donde esto es útil es escribir funciones asíncronas que se pasan callbacks como argumentos

var callback = function() { console.log('done', result)}

var dosomething = function(callback) {
    //do some stuff here
    ...
    result = 1;
    callback(result);
}

Dado que las funciones son objetos en javascript, también puede extenderlas con propiedades y métodos.

 2
Author: joidegn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 15:04:42

Cuando asigna una función a una variable, puede pasarla como argumento a otras funciones, y también extenderla para hacer uso del modelo de objetos de Javascript.

 1
Author: lamplightdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 15:02:14

Las funciones en JavaScript son objetos; son valores, en otras palabras. Por lo tanto, puede siempre establecer una variable para referirse a una función independientemente de cómo se defina 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 también pueden tener sus propias propiedades.

 0
Author: Pointy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 15:01:43

Si declara una functionvariable, usando "var", dentro de una función, la variable solo se puede acceder a dentro de esa función. Al salir de la función, la variable se destruye. Estas variables se denominan variables locales. Puede tener variables locales con el mismo nombre en diferentes funciones, porque cada una es reconocida solo por la función en la que se declara.

 0
Author: Downpour046,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 15:03:58