2010-09-26 12 views
8

Sé que hay varias formas de definir una función en JavaScript. Dos de los más comunes son:¿Qué sucede en JavaScript cuando uso la declaración de la función C "tradicional"?

(1) function add (a, b) { 
     return a + b; 
    } 

(2) var add = function (a, b) { 
     return a + b; 
    } 

Me siento cómodo con la idea de una función como un objeto que se puede pasar en torno al igual que cualquier otra variable. Así que entiendo perfectamente lo que está haciendo (2). Está creando una función y asignando a add (digamos que esto está en el alcance global, entonces add es una variable global) dicha función. Pero entonces, ¿qué sucede si uso (1)? Ya sé que hace una diferencia en el orden de ejecución: si uso (1), puedo referirme a add() antes del punto en el código donde está definido add(), pero si uso (2) entonces tengo que asignar mi función a add antes de poder comience refiriéndose al add().

¿Es (1) un atajo para (2), aunque uno que se comporta como otros lenguajes de estilo C nos permite definir una función "debajo" del punto en el que se utiliza? ¿O es internamente un tipo diferente de función? ¿Cuál es más "en el espíritu" de JavaScript (si ese no es un término demasiado vago)? ¿Te limitarías a uno u otro, y si es así cuál?

Respuesta

6

Parece que ya está al tanto de las características principales de function declarations (1) y function expressions (2). También tenga en cuenta que en (1) todavía hay una variable local llamada add que contiene un valor de función, al igual que en (2):

function hello() { 
    alert('Hello World'); 
} 

console.log(typeof hello); // prints "function" 

setTimeout(hello, 1000); // you can still pass functions around as arguments, 
          // even when using function declarations. 

Otro punto digno de mención es que declaraciones de funciones (1) shouldn' se puede usar para definir funciones de forma condicional (como en las declaraciones if), porque como mencionó, el intérprete de JavaScript las mueve automáticamente a la parte superior del ámbito de aplicación. Esto se conoce normalmente como hoisting.

En cuanto a qué enfoque es más en el espíritu de JavaScript, prefiero usar expresiones de función (2). Para obtener una opinión más autorizada, Douglas Crockford enumera las declaraciones de funciones (1) en el capítulo "Piezas defectuosas" en su popular The Good Parts book .


tambien conocido como sentencias de función (Ver @Tim Down's comentarios más abajo).
En realidad, algunos navegadores son capaces de manejar declaraciones de funciones en if declaraciones (consulte nuevamente los comentarios a continuación).
JavaScript: The Good Parts - Apéndice B: Página 113.

+2

Una declaración de función dentro del bloque de una instrucción 'if' es un error de sintaxis, de acuerdo con la especificación ECMAScript. Ninguno de los principales navegadores arroja un error, probablemente debido al precedente establecido por IE y Mozilla. Mozilla lo soluciona incluyendo una extensión a ECMAScript llamada 'FunctionStatement' (http://www.jibbering.com/faq/#functionStatement, http://kangax.github.com/nfe/#function-statements). JScript tiene menos respeto por la especificación y sabe Dios qué internamente. –

+1

Un comentario sobre su edición: es cierto que las declaraciones de funciones también se conocen como declaraciones de funciones, pero incorrectamente. Las preguntas frecuentes de comp.lang.javascript (vinculadas a en mi comentario anterior) hacen que este punto sea muy elocuente: * "El enunciado de función de término ha sido usado de manera amplia e incorrecta para describir una 'FunctionDeclaration'. Esto es engañoso porque en ECMAScript,' FunctionDeclaration 'no es un' Statement'; hay lugares en un programa donde se permite un 'Statement' pero no un' FunctionDeclaration'. "* –

+0

@Tim: Gracias por los comentarios interesantes. No estaba al tanto del problema de nombres de "declaración". –

2
function foo() {}; 
foo.toString() //-> "function foo() {}" 

var bar = foo; 
bar.toString() //-> "function foo() {}" 

Por lo tanto, se declara una función llamada. No importa qué variable lo señale, su nombre se conserva.Usar la otra sintaxis es una función anónima, que no tiene nombre y solo se puede acceder a ella si se hace referencia a ella mediante una variable.

var foo = function() {}; 
foo.toString() //-> "function() {}" 

var bar = foo; 
bar.toString() //-> "function() {}" 

En cuanto a qué estilo usar, no hay una regla principal. Aunque personalmente estoy a favor de la sintaxis anónima, ya que me recuerda que las funciones son, de hecho, objetos que pueden transmitirse. También tiendo a favorecer el enfoque "todo está en un gran objeto maestro", que requiere que las funciones se declaren de esta manera.

var MyThingy = { 
    foo: function() { alert('foo') }, 
    bar: function() { MyThingy.foo() } 
} 

Pero después de que se crean las funciones, las diferencias no son realmente importantes y se comportan igual. Pero la sintaxis anónima tiene menos de magia de exploración que usted mencionó, y hay menos errores en el código complejo y situaciones de alcance extraño.

Cuestiones relacionadas