Funciones
En JavaScript, declaramos funciones usando la palabra reservada function antes del nombre de la función. Los parámetros que le pasaremos a la función van dentro del paréntesis tras el nombre de la misma. Una vez definida la función, entre las llaves declaramos el cuerpo de la misma. El nombre de las funciones (como el de las variables) se suele escribir en formato camelCase con la primera letra en minúsculas.
Para ejecutar la función basta con poner el nombre de la misma en el código pasándole los valores de cada parámetro entre los paréntesis. Aunque no reciba ningún valor, los paréntesis son obligatorios en la llamada.
No necesitas tener la función declarada antes de la llamada, esto es debido a que el motor de ejecución de JavaScript hace 2 pasadas. Primero procesa las declaraciones de variables y funciones, y después ejecuta el programa.
Podemos llamar a una función enviándole más o menos parámetros de los establecidos en la declaración. Si le enviamos más parámetros, los sobrantes serán ignorados y si le enviamos menos, a los no recibidos se les asignará el valor undefined.
Retorno de valores
Podemos usar la palabra reservada return para devolver un valor en una función. Si intentamos acceder al valor de una función que no devuelve nada, obtendremos undefined.
Es conveniente recordar que en cuanto se ejecuta la instrucción return, la función termina inmediatamente devolviendo el valor correspondiente. No tiene sentido tener instrucciones de código después de la instrucción return, a no ser que haya una estructura condicional que discrimine entre varias opciones a la hora de devolver un valor.
Funciones anónimas
La forma de declarar una función anónima es no asignarle ningún nombre. Podemos asignar dicha función como valor a una variable, ya que es un tipo de valor (como puede ser un string o número), por tanto, puede ser asignada a (o referenciada desde) múltiples variables. Se utiliza igual que una función clásica.
Funciones flecha (o lambda)
Una de las funcionalidades más importantes que se añadió en ES2015 fue la posibilidad de usar las funciones lambda (o flecha). Otros lenguajes como C#, Java, etc. también las soportan. Estas expresiones ofrecen la posibilidad de crear funciones anónimas pero con algunas ventajas.
Vamos a ver las diferencias que tiene por creando dos funciones equivalentes (una anónima y otra lambda que hacen lo mismo):
Cuando declaramos una función flecha o lambda, la palabra reservada function no se usa. Si sólo se recibe un parámetro, los paréntesis pueden ser omitidos. Después de los parámetros debe ir una flecha (=>), y el contenido de la función.
Si sólo hay una instrucción dentro de la función flecha, podemos omitir las llaves '{}'. En este caso debemos omitir la palabra reservada return ya que lo hace de forma implícita (devuelve el resultado de esa instrucción). Si hay más de una instrucción, usamos las llaves y se comporta como una función normal, y por tanto si devuelve algo, debemos usar la palabra reservada return.
La diferencia más importante entre ambos tipos de funciones es el comportamiento de la palabra reservada this. Pero eso lo veremos en el bloque de Programación orientada a objetos.
Parámetros por defecto
Si un parámetro se declara en una función y no se le pasa un valor cuando la llamamos, se establece su valor como undefined.
Una solución usada para establecer un valor por defecto era usar el operador '||' (or), de forma que si se evalúa como undefined (equivale a false), se le asigna otro valor por defecto.
Desde ES2015 tenemos la opción de establecer un valor por defecto directamente.
También podemos asignarle un valor por defecto basado en una expresión.
Ámbito de las variables
Variables globales
Cuando se declara una variable en el bloque principal (fuera de cualquier función), ésta es creada como global. Las variables que no son declaradas con la palabra reservada let son también globales (a menos que estemos usando el strict mode, que no permite hacer esto).
A una variable global podremos acceder desde cualquier parte del código. Esto es peligroso desde el punto de vista de prevenir efectos colaterales cuando se modifica su valor, por lo que se recomienda evitar este tipo de variables cuando no sea estrictamente necesario.
Si olvidamos poner la palabra let al declarar una variable dentro de una función, Si no usas strict mode (Es recomendable que lo uses), se creará una variable global. En el modo estricto no te permitirá hacer eso.
Variables locales
Todas las variables que se declaran dentro de una función u otro tipo de bloque (if, while, ...) son locales a dicho bloque. Es decir, solo pueden ser accedidas desde el bloque donde son declaradas (incluyendo otros bloques que estén dentro del mismo), pero no desde fuera.
Si una variable global con el mismo nombre existe, la variable local no actualizará el valor de la variable global.