Las funciones son la piedra angular en la programación, los trozos de código que hacen una cosa a la vez.
Las funciones en cualquier lenguaje son una serie de procedimientos o instrucciones que realizan una acción. Una ventaja de las funciones es que permiten tener un código más ordenado y fácil de mantener.
Otra ventaja de las funciones es que son reutilizables, puedes tener una función que valide un formulario y utilizarla en todos tus formularios, puedes tener también una función que envíe datos al servidor y reutilizarla múltiples veces.
Existen 2 formas de crear funciones en JavaScript.
Declaración de función (function declaration)
La expresión de la función utiliza la palabra reservada function, seguida de un nombre y un paréntesis, en este paréntesis se colocan los argumentos, finalmente el cuerpo de la función se define por unas llaves.
function sumar() {
console.log(2 + 2);
}
// Las funciones deben llamarse, de otra forma en realidad no hacen mucho:
sumar(); //Se manda llamar por su nombre seguido del paréntesis()
Expresión de función (function expression)
Este tipo de funciones se asigna como si fuera una variable
const sumar2 = function() {
console.log(3 + 3);
}
sumar2(); //Se manda llamar de la misma forma
Existe una 3ra forma de crear funciones, que más bien son métodos, la veremos un poco más adelante.
Hoisting – La diferencia entre la declaración y la expresión de una función
Ademas de las muy notables diferencias en sintaxis, quiero mostrarte las diferencias entre ambas. Si llamamos la función antes de declararla, el function declaration va a funcionar bien, mientras que el otro nos va a marcar un error.
sumar(); //
function sumar() {
console.log(2 + 2);
}
sumar2();
const sumar2 = function() {
console.log(3 + 3);
}
Eso pasa porque JavaScript se ejecuta digamos en 2 vueltas. Eso se le conoce como Hoisting , la primera vuelta registra todas las funciones y determina las variables, esta etapa se le llama de creación, la segunda pasada es la que ejecuta el código, se llama de ejecución.
Por lo tanto el primer código funciona porque function se registra primero y después se ejecuta el código. Pero el segundo no funciona porque si bien es una función no es declarada como tal, lo ve más bien como una variable.
Esto se le conoce como hosting que básicamente son esas 2 etapas (creación y ejecución), básicamente tu código se ejecuta asi:
const sumar2;
sumar2(); // a estas alturas es undefined…
sumar2 = function() {
console.log(3 + 3); // pero como ya habíamos llamado la función, se queda como undefined
}
// Y esta es pregunta para obtener un trabajo como JS Developer
Mucho de lo que se escribió arriba es tomado directamente de las anotaciones del instructor del curso. Entiendo perfectamente que la expresión de función no va a funcionar correctamente si la mando a llamar antes de crearla por un tema de dos vueltas que hace JavaScript que se llama Hoisting ya que en la primera vuelta JavaScript va a ver más una declaración de variable que un función. Esto no va a pasar con el método de declaración de función porque en la primera vuelta el proceso va a leer perfectamente la función que para la segunda vuelta ejecutará perfectamente la función.
Pero hay otras cosas a tomar en cuenta
Entonces para resumir, he encontrado un buen material en la web sobre todo esto que procedo a pegar a continuación.
Expresiones de función
En JavaScript, una función no es una «estructura de lenguaje mágico», sino un tipo especial de valor.
La sintaxis que usamos antes se llama declaración de función :
function sayHi() {
alert( "Hello" );
}
Hay otra sintaxis para crear una función que se llama expresión de función .
Nos permite crear una nueva función en medio de cualquier expresión.
Por ejemplo:
let sayHi = function() {
alert( "Hello" );
};
Aquí podemos ver una variable sayHi
obteniendo como valor la nueva función, creada como function() { alert("Hello"); }
.
Como la creación de la función ocurre en el contexto de la expresión de asignación (a la derecha de =), esta es una expresión de función .
Tenga en cuenta que no hay ningún nombre después de la palabra reservada function. Se permite omitir un nombre para las expresiones de función.
Aquí lo asignamos inmediatamente a la variable, por lo que el significado de estos ejemplos de código es el mismo: «crear una función y ponerla en la variable sayHi«.
En situaciones más avanzadas, que veremos más adelante, se puede crear una función e inmediatamente llamarla o programarla para una ejecución posterior, no almacenarla en ningún lado, permaneciendo así anónima.
La función es un valor
Reiteremos: no importa cómo se cree la función, una función es un valor. Ambos ejemplos anteriores almacenan una función en la variable sayHi
.
Incluso podemos imprimir ese valor usando alert
:
function sayHi() {
alert( "Hello" );
}
alert( sayHi ); // shows the function code
Tenga en cuenta que la última línea no ejecuta la función, porque no hay paréntesis después de sayHi. Hay lenguajes de programación donde cualquier mención del nombre de una función provoca su ejecución, pero JavaScript no es así.
En JavaScript, una función es un valor, por lo que podemos tratarla como un valor. El código anterior muestra su representación de cadena, que es el código fuente.
Seguramente, una función es un valor especial, en el sentido de que podemos llamarlo como sayHi().
Pero sigue siendo un valor. Entonces podemos trabajar con él como con otros tipos de valores.
Podemos copiar una función a otra variable:
function sayHi() { // (1) create
alert( "Hello" );
}
let func = sayHi; // (2) copy
func(); // Hello // (3) run the copy (it works)!
sayHi(); // Hello // this still works too (why wouldn't it)
Esto es lo que sucede arriba en detalle:
- La declaración de función (1) crea la función y la coloca en la variable denominada sayHi.
- Lo copia (2) en la variable func. Tenga en cuenta nuevamente: no hay paréntesis después de sayHi. Si lo hubiera, func = sayHi() escribiría el resultado de la llamada sayHi() en func, no la función sayHi en sí.
- Ahora la función se puede llamar tanto sayHi() como con func().
También podríamos haber usado una expresión de función para declarar sayHi, en la primera línea:
let sayHi = function() { // (1) create
alert( "Hello" );
};
let func = sayHi;
// ...
Todo funcionaría igual.
¿Por qué hay un punto y coma al final? Quizás se pregunte, ¿por qué la expresión de la función tiene un punto y coma ;al final, pero la declaración de la función no? function sayHi() { // ... } let sayHi = function() { // ... }; La respuesta es simple: aquí se crea una expresión de función como function(…) {…}dentro de la instrucción de asignación: let sayHi = …;. Se recomienda el punto y coma ;al final de la declaración, no es parte de la sintaxis de la función. El punto y coma estaría ahí para una asignación más simple, como let sayHi = 5;, y también está ahí para una asignación de función.
Expresión de función frente a declaración de función
Formulemos las diferencias clave entre declaraciones de funciones y expresiones.
Primero, la sintaxis: cómo diferenciarlos en el código.
- Declaración de función: una función, declarada como una declaración separada, en el flujo de código principal.
// Function Declaration
function sum(a, b) {
return a + b;
}
- Expresión de función: una función, creada dentro de una expresión o dentro de otra construcción de sintaxis. Aquí, la función se crea en el lado derecho de la «expresión de asignación» =:
// Function Expression
let sum = function(a, b) {
return a + b;
};
La diferencia más sutil es cuando el motor de JavaScript crea una función.
Una expresión de función se crea cuando la ejecución la alcanza y solo se puede usar a partir de ese momento.
Una vez que el flujo de ejecución pasa al lado derecho de la asignación let sum = function…, aquí vamos, la función se crea y se puede usar (asignar, llamar, etc.) de ahora en adelante.
Las declaraciones de funciones son diferentes.
Una declaración de función se puede llamar antes de que se defina.
Por ejemplo, una declaración de función global es visible en todo el script, sin importar dónde se encuentre.
Eso se debe a algoritmos internos. Cuando JavaScript se prepara para ejecutar el script, primero busca declaraciones de funciones globales en él y crea las funciones. Podemos pensar en ello como una “etapa de inicialización”.
Y después de que se procesan todas las declaraciones de funciones, se ejecuta el código. Así que tiene acceso a estas funciones.
Por ejemplo, esto funciona:
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
La declaración de función sayHi se crea cuando JavaScript se está preparando para iniciar el script y es visible en todas partes.
Si fuera una expresión de función, entonces no funcionaría:
sayHi("John"); // error!
let sayHi = function(name) { // (*) no magic any more
alert( `Hello, ${name}` );
};
Las expresiones de función se crean cuando la ejecución las alcanza. Eso ocurriría sólo en la línea (*). Demasiado tarde.
Otra característica especial de las declaraciones de función es su ámbito de bloque.
En modo estricto, cuando una declaración de función está dentro de un bloque de código, es visible en todas partes dentro de ese bloque. Pero no fuera de ella.
Por ejemplo, imaginemos que necesitamos declarar una función welcome() dependiendo de la variable age que obtengamos durante el tiempo de ejecución. Y luego planeamos usarlo algún tiempo después.
Si usamos declaración de función, no funcionará como se esperaba:
let age = prompt("What is your age?", 18);
// conditionally declare a function
if (age < 18) {
function welcome() {
alert("Hello!");
}
} else {
function welcome() {
alert("Greetings!");
}
}
// ...use it later
welcome(); // Error: welcome is not defined
Esto se debe a que una declaración de función solo es visible dentro del bloque de código en el que reside.
Aquí hay otro ejemplo:
let age = 16; // take 16 as an example
if (age < 18) {
welcome(); // \ (runs)
// |
function welcome() { // |
alert("Hello!"); // | Function Declaration is available
} // | everywhere in the block where it's declared
// |
welcome(); // / (runs)
} else {
function welcome() {
alert("Greetings!");
}
}
// Here we're out of curly braces,
// so we can not see Function Declarations made inside of them.
welcome(); // Error: welcome is not defined
¿Qué podemos hacer para hacer welcome visible en el exterior de if?
El enfoque correcto sería utilizar una expresión de función y asignar welcome a la variable que se declara fuera de if y tiene la visibilidad adecuada.
Este código funciona según lo previsto:
let age = prompt("What is your age?", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("Hello!");
};
} else {
welcome = function() {
alert("Greetings!");
};
}
welcome(); // ok now
O podríamos simplificarlo aún más usando un operador de signo de interrogación ?:
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
function() { alert("Hello!"); } :
function() { alert("Greetings!"); };
welcome(); // ok now
¿Cuándo elegir Declaración de función versus Expresión de función? Como regla general, cuando necesitamos declarar una función, lo primero que debemos considerar es la sintaxis de declaración de función. Da más libertad en cómo organizar nuestro código, porque podemos llamar a tales funciones antes de que sean declaradas. Eso también es mejor para la legibilidad, ya que es más fácil buscar function f(…) {…} en el código que let f = function(…) {…};. Las declaraciones de funciones son más "llamativas". Pero si una Declaración de función no nos conviene por alguna razón, o necesitamos una declaración condicional (acabamos de ver un ejemplo), entonces se debe usar Expresión de función.
Resumen
- Las funciones son valores. Se pueden asignar, copiar o declarar en cualquier lugar del código.
- Si la función se declara como una declaración separada en el flujo de código principal, eso se denomina «Declaración de función».
- Si la función se crea como parte de una expresión, se denomina «Expresión de función».
- Las declaraciones de función se procesan antes de que se ejecute el bloque de código. Son visibles en todas partes en el bloque.
- Las expresiones de función se crean cuando el flujo de ejecución las alcanza.
En la mayoría de los casos, cuando necesitamos declarar una función, es preferible una declaración de función, porque es visible antes de la declaración misma. Eso nos da más flexibilidad en la organización del código y, por lo general, es más legible.
Por lo tanto, debemos usar una expresión de función solo cuando una declaración de función no sea adecuada para la tarea. Hemos visto un par de ejemplos de eso en este capítulo, y veremos más en el futuro.