2009-12-18 12 views
77

Duplicar posibles:
Javascript: var functionName = function() {} vs function functionName() {}Declaración de funciones en JavaScript

¿Cuál es la diferencia entre estas dos formas de declarar una función?

function someFunc() { ... } 

var someFunc = function() { ... } 

No estoy preguntando en el sentido técnico. No estoy preguntando qué es mejor para la legibilidad, o qué estilo es el preferido.

+9

duplicados de http://stackoverflow.com/questions/336859/javascript-var-functionname-function-vs-function- nombre de función –

Respuesta

42

Estoy en una opinión diferente con la mayoría de la gente aquí. Técnicamente esta sintaxis puede significar lo mismo para declarar funciones en ambos sentidos (que destacan incorrecta en mi última declaración. He leído en un poste diff por qué son técnicamente diff y voy a añadir, al final, ¿por qué) ; pero la forma en que juegan un papel en la evolución de los patrones es masiva. Recomiendo encarecidamente "Javascript: The Good Parts" de Doughlas Crockford.

Pero para demostrar mi punto de una manera sutil y simple; aquí hay un pequeño ejemplo.

//Global function existing to serve everyone 
function swearOutLoud(swearWord) { 
    alert("You "+ swearWord);   
} 
//global functions' territory ends here 

//here is mr. spongebob. He is very passionate about his objects; but he's a bit rude. 
var spongeBob = { 
    name : "squarePants", 
    swear : function(swearWord) { 
       name = "spongy"; 
       alert("You "+ swearWord); 
       return this; 
      } 
} 

//finally spongebob learns good manners too. EVOLUTION! 
spongeBob.apologize = function() { 
    alert("Hey " + this.name + ", I'm sorry man!"); 
    return this; 
} 


//Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!) 
alert(spongeBob.swear("twit").apologize()); 

Si mira el código anterior, he declarado una función con el nombre swearOutLoud. Que tomaría una maldición de cualquier objeto o una llamada y le dará la salida. Puede hacer operaciones en cualquier objeto usando el parámetro "this" que se le pasa y los argumentos.

Sin embargo, la segunda declaración se declara como un atributo del objeto llamado "spongeBob". Esto es importante tener en cuenta; como aquí me estoy moviendo hacia un comportamiento orientado a objetos. Mientras también mantengo el "efecto de cascada", devuelvo "esto" si no tengo nada más que devolver.

Algo similar se hace en jquery; y este patrón en cascada es importante si estás tratando de escribir un marco o algo así. Lo vinculará al patrón de diseño de Builder también.

Pero con las funciones declaradas como atributos de un objeto, puedo lograr un comportamiento centrado en el objeto que conduce a un mejor paradigma de programación. A menos que esté bien diseñado; las funciones individuales declaradas fuera con acceso global conducen a una forma de codificación no orientada a objetos. De alguna manera prefiero lo último.

Para ver la cascada en efecto, mira la última declaración en la que puedes pedirle a spongebob que jure y se disculpe de inmediato; aunque se haya agregado una disculpa como atributo más adelante.

Espero aclarar mi punto. La diferencia desde una perspectiva técnica puede ser pequeña; pero desde el punto de vista del diseño y la evolución del código, es enorme y hace una gran diferencia.

¡Pero eso soy yo! Tómelo o déjelo. :)

EDIT:

Así tanto las llamadas son técnicamente diferentes; porque una declaración con nombre está vinculada al espacio de nombres global y se define en el tiempo de análisis. Entonces se puede llamar incluso antes de declarar la función.

//success 
swearOutLoud("Damn"); 

function swearOutLoud(swearWord) { 
    alert("You " + swearWord) 
} 

El código anterior funcionará correctamente. Pero el código a continuación no.

swear("Damn!"); 
    var swear = function(swearWord) { 
    console.log(swearWord); 
} 
+26

La parte principal de esto no está clara y no tiene nada que ver con la pregunta. –

+0

Tal vez, pero por otro lado, Bob Esponja te está hablando – Mozgor

12

Una ventaja del uso de function someFunc() { ... } es que el nombre de la función aparece en el depurador Firebug. Las funciones que se declaran de otra manera (var someFunc = function() { ... }) aparecen como anónimo.

4

En realidad, la diferencia es que la segunda declaración nos da la capacidad de declarar funciones como esto por lo que es posible tener una función como una propiedad de un objeto:

var myObject=new Object(); 
myObject.someFunc=function() { ... }; 
1

Cuando se escribe

function Test() { 
} 

JavaScript realmente está creando una propiedad a la que asigna el objeto de función que una vez llamado ejecutará el código informado en la definición de la función. La propiedad se adjunta al objeto window, o al objeto que contiene la definición de la función.

+1

Aquí tiene algunos conceptos erróneos: primero, existe una diferencia entre las funciones nombradas y las anónimas en JavaScript, como puede ver llamando a 'toString' en una función. Segundo, si bien es cierto que una declaración de función agrega una propiedad al objeto varibale actual, ese es solo el objeto global (también conocido como 'ventana' en los navegadores) en código global (en lugar de dentro de una función, por ejemplo). Como resultado, su tercer párrafo es completamente falso. (continúa ...) –

+1

... Tercero, hay una diferencia en cuando la función se asigna al objeto variable. Las funciones creadas por una declaración de función (p. Ej. 'Function test() {}') pueden usarse en el código que aparece antes, que no es verdadero para las funciones declaradas por una expresión de función (p. Ej. 'Var test = function() {}; ') –

+1

Eso no es lo que se informa en" JavaScript: The Definitive Guide ", que establece claramente" Cuando el analizador de JavaScript encuentra una definición de función, analiza y almacena (sin ejecutar) el cuerpo de la función. propiedad (en el objeto de llamada si la definición de función está anidada con otra función; de lo contrario, en el objeto global) con el mismo nombre que la función para mantener la función. – kiamlaluno

1

Para la legibilidad, yo diría que el primero es claramente mejor. Un programador de mantenimiento futuro, incluso asumiendo que están lo suficientemente familiarizados con javascript para conocer muchos de los puntos más finos que surgen en este hilo, van a asumir el primer formato.

Por ejemplo, si algún día quisieran ctrl-f para buscar la definición de su función para ver qué ocurre allí, ¿van a buscar primero someFunc = function() o function someFunc()?

Además, para ser francamente tipográfico al respecto (ya que hablamos de readabilidad) los lectores a menudo escanean el texto rápidamente, y estarían más inclinados a omitir una línea que comienza con "var" si están buscando una definición de función.

Sé que esta es una respuesta no técnica, pero es más difícil para los humanos leer código que las computadoras.

2

Otra diferencia es que, en la mayoría de los navegadores, este último le permite definir diferentes implementaciones según las circunstancias, mientras que el primero no. Supongamos que quiere una suscripción a eventos entre navegadores. Si se trató de definir una función addEventListenerTo así:

if (document.addEventListener) { 
    function addEventListenerTo(target, event, listener) { 
     .... 
    } 
} else if (document.attachEvent) { 
    function addEventListenerTo(target, event, listener) { 
     .... 
    } 
} else { 
    function addEventListenerTo(target, event, listener) { 
     .... 
    } 
} 

en algunos navegadores, todas las funciones terminan siendo analizado, con el último que tiene prioridad. Resultado: lo anterior simplemente no funciona. Sin embargo, la asignación de funciones anónimas a variables funcionará. También puede aplicar técnicas funcionales y básicas aspect oriented programming utilizando funciones anónimas asignadas a variables.

var fib = memoize(function (n) { 
    if (n < 0) return 0; 
    if (n < 2) return 1; 
    return fib(n-1) + fib(n-2); 
}); 

... 
// patch the $ library function 
if (...) { 
    $ = around($, fixArg, fixResult); 
} 
2

Es a la vez cierto que la primera forma:

function test() { } 

es una sintaxis más reconocido y que la segunda forma:

var test = function() { ... } 

le permite controlar el alcance de la función (mediante el uso de var; sin él, sería global de todos modos).

e incluso se puede hacer ambas cosas:

var test = function test() { ... test(); ... } 

Esto le permite definir una función recursiva en la segunda forma.

+1

No estoy de acuerdo con que la primera forma sea una sintaxis más reconocida y que la segunda forma. Son solo formas diferentes, btoh de las cuales son de uso común. Además, las expresiones de funciones nombradas (que es lo que estás usando en el último ejemplo) tienen un comportamiento extraño en IE. Vea el siguiente artículo: http://yura.thinkweb2.com/named-function-expressions/ –

4

Estilo sabia el segundo ejemplo es más coherente con otras formas comunes para declarar funciones y por lo tanto se podría argumentar que es más fácil de leer

this.someFunc = function() { ... } 
... 
someFunc: function() { ... }, 

Sin embargo, como también se menciona que es anónima y por lo tanto el nombre no hace aparecer al perfilar. Otra manera de declarar la función es la siguiente que se obtiene lo mejor de ambos mundos

var someFunc = function someFunc() { ... } 
Cuestiones relacionadas