Funciones

Una función es un bloque modular y reutilizable de sentencias que se usa para realizar un conjunto de tareas relacionadas, como calcular y mostrar un valor según los argumentos proporcionados a la función. Al igual que con todos los valores no primitivos, las funciones son objetos. Son objetos únicos porque se los puede llamar para ejecutar código, pasar datos en forma de argumentos y return un valor.

Se consideran funciones como objetos de "primera clase", lo que significa que, a pesar de su comportamiento único, pueden usarse en los mismos contextos que cualquier otro objeto de JavaScript. Por ejemplo, una función puede asignarse a una variable, pasarse como argumento a otras funciones y ser devuelta por otras funciones.

function myFunction() {
   console.log( "This is my function." );
};

Una función definida como una propiedad de un objeto se suele denominar "método". Al igual que con las variables declaradas con var, las declaraciones de funciones realizadas fuera de una función contenedora se agregan al objeto global como métodos.

Declaraciones de funciones

Una declaración de función (también llamada "declaración de funciones" o "definición de la función") crea una función con nombre que se puede invocar en otro lugar del alcance que la contiene. Las declaraciones de funciones constan de la palabra clave function seguida de un identificador, una lista de parámetros separados por comas encerrados entre paréntesis y una declaración de bloque denominada "cuerpo de la función". Con frecuencia, encontrarás declaraciones de función que no terminan con punto y coma. Debido a que una declaración de función es una instrucción, el punto y coma final se puede inferir por ASI.

function myFunction() {
   console.log( "This is my function." );
};

myFunction();
> "This is my function."

Como retención de las decisiones iniciales de diseño de JavaScript, las declaraciones de funciones están sujetas al mismo comportamiento de elevación heredado que las variables declaradas con var, lo que significa que una declaración de función se eleva a la parte superior de su alcance y se puede llamar antes de la declaración como resultado, sin importar si ese alcance está regido o no por el modo estricto:

"use strict";
{
    myFunction();
    function myFunction() {
        console.log( "This is my function." );
    };
}
> "This is my function."

Fuera del modo estricto, las declaraciones de funciones usan el comportamiento de alcance heredado de JavaScript, lo que significa que una declaración de función tiene alcance en función de la función contenedora más cercana:

function myFunction() {
    function myNestedFunction() {
        console.log( "This is my nested function." );
    }
    myNestedFunction();
};

myFunction();
> "This is my nested function."

myNestedFunction();
>Uncaught ReferenceError: myNestedFunction is not defined

En el modo estricto, las declaraciones de funciones tienen alcance a su bloque contenedor más cercano, como es el caso de las variables declaradas mediante let o const:

"use strict";
{
    function myFunction() {
        console.log( "This is my function." );
    };
}

myFunction();
> Uncaught ReferenceError: myFunction is not defined

Llamada a función

Al igual que con las variables, el identificador que se usa cuando se declara una función actúa como un nombre simbólico de un valor. Hacer referencia a una función solo por identificador muestra solo el objeto de la función y no ejecuta la función que contiene:

function myFunction() {
   console.log( "This is my function." );
};

myFunction;
> myFunction() {
   console.log( "This is my function." );
}

Para ejecutar el código dentro del cuerpo de la función, llama (o invoca) a la función siguiendo el nombre de la función con un par de paréntesis coincidente:

function myFunction() {
    console.log( "My function has been executed." );
}

myFunction();
> "My function has been executed."

Los parámetros en la definición de la función actúan como variables de marcador de posición para los valores que se pueden pasar al cuerpo de la función cuando se la llama. Los valores entre paréntesis cuando se llama a una función son "argumentos" (aunque es posible que veas "argumentos" utilizados para describir argumentos y parámetros en alguna documentación):

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

Si se omite un argumento esperado, el parámetro resultante contiene un valor undefined porque se declara el parámetro en el cuerpo de la función, pero no se inicializa con un valor:

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction();
> "The value is: undefined."

Para configurar los valores predeterminados de los parámetros, inicialízalos de la misma manera en que inicializarías una variable: un operador de asignación (=) seguido de un valor. Si más adelante especificas un argumento para esa función, ese valor nuevo anula el valor predeterminado:

function myFunction( myParameter = "omitted" ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

myFunction();
> "The value is: omitted."

El cuerpo de una función no de flecha también tiene acceso a un objeto arguments tipo array con índice cero que contiene todos los valores pasados como argumentos, sin importar si la definición de la función especifica parámetros o no:

function myFunction() {
   console.log( arguments );
};

myFunction( 3, true, "My string" );
> Arguments { 0: 3, 1: true, 2: "My string", … }

Funciones variables

El objeto arguments te permite crear funciones varádicas básicas, que pueden aceptar una cantidad variable de argumentos:

function myFunction() {
    let result = "";
    for (let i = 0; i < arguments.length; i++) {
        result += arguments[i] + " - ";
    }
    console.log( result );
};

myFunction( "My first string", "My second string", "my third string" );\
> "My first string - My second string - my third string - "

Sin embargo, este enfoque para las funciones variádicas rara vez se usa en el desarrollo moderno de JavaScript. Es más común usar la sintaxis del parámetro de REST más moderna y legible, que crea un parámetro con nombre inicializado como un array que contiene cualquier argumento más allá de los especificados de manera explícita:

function myFunction( mySeparator, ...myStrings ) {
  console.log( myStrings.join( mySeparator ) );
};

myFunction( " - ", "My first string", "My second string", "my third string" );
> "My first string - My second string - my third string"

A diferencia de la vinculación de parameter, la sintaxis del parámetro de REST funciona como se espera con los parámetros de la función de flecha:

function myOuterFunction() {
    let myInnerArrowFunction = ( ...myParams ) => {
        console.log( myParams[ 0 ] );
    }
    myInnerArrowFunction( true );
};

myOuterFunction( false );
> true

let myArrowFunction = ( ...myParams ) => {
    console.log( myParams[ 0 ] );
};

myArrowFunction( true );
> true`
``