ES6 - Funciones

Functionsson los bloques de construcción de código legible, mantenible y reutilizable. Las funciones se definen mediante la palabra clave de función. A continuación se muestra la sintaxis para definir una función estándar.

function function_name() { 
   // function body 
}

Para forzar la ejecución de la función, se debe llamar. Esto se llama invocación de función. A continuación se muestra la sintaxis para invocar una función.

function_name()

Ejemplo: definición de función simple

//define a  function 
function test() { 
   console.log("function called") 
} 
//call the function 
test()

El ejemplo define una función test (). Un par de delimitadores ({}) definen el cuerpo de la función. También se le llama comofunction scope. Se debe invocar una función para forzar su ejecución.

La siguiente salida se muestra en la ejecución exitosa del código anterior.

function called

Clasificación de funciones

Las funciones se pueden clasificar como Returning y Parameterized funciones.

Funciones de retorno

Las funciones también pueden devolver el valor junto con el control a la persona que llama. Estas funciones se denominan funciones de retorno.

A continuación se muestra la sintaxis de la función de devolución.

function function_name() { 
   //statements 
   return value; 
}
  • Una función de retorno debe terminar con una declaración de retorno.

  • Una función puede devolver como máximo un valor. En otras palabras, solo puede haber una declaración de retorno por función.

  • La declaración de retorno debe ser la última declaración de la función.

El siguiente fragmento de código es un ejemplo de una función de devolución:

function retStr() { 
   return "hello world!!!" 
}  
var val = retStr() 
console.log(val)

El ejemplo anterior define una función que devuelve la cadena "¡¡¡hola mundo !!!" a la persona que llama. La siguiente salida se muestra en la ejecución exitosa del código anterior.

hello world!!!

Funciones parametrizadas

Los parámetros son un mecanismo para pasar valores a funciones. Los parámetros forman parte de la firma de la función. Los valores de los parámetros se pasan a la función durante su invocación. A menos que se especifique explícitamente, el número de valores pasados ​​a una función debe coincidir con el número de parámetros definidos.

A continuación se muestra la sintaxis que define una función parametrizada.

function func_name( param1,param2 ,…..paramN) {   
   ...... 
   ...... 
}

Example − Parameterized Function

El ejemplo define una función add que acepta dos parámetros n1 y n2e imprime su suma. Los valores de los parámetros se pasan a la función cuando se invoca.

function add( n1,n2) { 
   var sum = n1 + n2 
   console.log("The sum of the values entered "+sum) 
} 
add(12,13)

La siguiente salida se muestra en la ejecución exitosa del código anterior.

The sum of the values entered 25

Parámetros de función predeterminados

En ES6, una función permite que los parámetros se inicialicen con valores predeterminados, si no se le pasan valores o no está definido. Lo mismo se ilustra en el siguiente código.

function add(a, b = 1) { 
   return a+b; 
} 
console.log(add(4))

La función anterior establece el valor de b en 1 por defecto. La función siempre considerará que el parámetro b tiene el valor 1 a menos que se haya pasado explícitamente un valor. La siguiente salida se muestra en la ejecución exitosa del código anterior.

5

El valor predeterminado del parámetro se sobrescribirá si la función pasa un valor explícitamente.

function add(a, b = 1) { 
   return a + b; 
} 
console.log(add(4,2))

El código anterior establece el valor del parámetro b explícitamente en 2, sobrescribiendo así su valor predeterminado. La siguiente salida se muestra en la ejecución exitosa del código anterior.

6

Para una mejor comprensión, consideremos el siguiente ejemplo.

Ejemplo 1

El siguiente ejemplo muestra una función que toma dos parámetros y devuelve su suma. El segundo parámetro tiene un valor predeterminado de 10. Esto significa que, si no se pasa ningún valor al segundo parámetro, su valor será 10.

<script>
   function addTwoNumbers(first,second = 10){
      console.log('first parameter is :',first)
      console.log('second parameter is :',second)
      return first+second;
   }

   console.log("case 1 sum:",addTwoNumbers(20)) // no value
   console.log("case 2 sum:",addTwoNumbers(2,3))
   console.log("case 3 sum:",addTwoNumbers())
   console.log("case 4 sum",addTwoNumbers(1,null))//null passed
   console.log("case 5 sum",addTwoNumbers(3,undefined))
</script>

La salida del código anterior será la que se menciona a continuación:

first parameter is : 20
second parameter is : 10
case 1 sum: 30
first parameter is : 2
second parameter is : 3
case 2 sum: 5
first parameter is : undefined
second parameter is : 10
case 3 sum: NaN
first parameter is : 1
second parameter is : null
case 4 sum 1
first parameter is : 3
second parameter is : 10
case 5 sum 13

Ejemplo 2

<script>
   let DEFAULT_VAL = 30
      function addTwoNumbers(first,second = DEFAULT_VAL){
         console.log('first parameter is :',first)
         console.log('second parameter is :',second)
         return first+second;
      }
      console.log("case 1 sum",addTwoNumbers(1))
      console.log("case 2 sum",addTwoNumbers(3,undefined))
</script>

La salida del código anterior será como se muestra a continuación:

first parameter is : 1
second parameter is : 30
case 1 sum 31
first parameter is : 3
second parameter is : 30
case 2 sum 33

Parámetros de descanso

Los parámetros de descanso son similares a los argumentos variables en Java. Los parámetros de descanso no restringen el número de valores que puede pasar a una función. Sin embargo, los valores pasados ​​deben ser todos del mismo tipo. En otras palabras, los parámetros rest actúan como marcadores de posición para múltiples argumentos del mismo tipo.

Para declarar un parámetro de descanso, el nombre del parámetro tiene como prefijo tres puntos, conocido como el operador de propagación. El siguiente ejemplo ilustra lo mismo.

function fun1(...params) { 
   console.log(params.length); 
}  
fun1();  
fun1(5); 
fun1(5, 6, 7);

La siguiente salida se muestra en la ejecución exitosa del código anterior.

0 
1 
3

Note - Los parámetros de descanso deben ser los últimos en la lista de parámetros de una función.

Función anónima

Las funciones que no están vinculadas a un identificador (nombre de la función) se denominan funciones anónimas. Estas funciones se declaran dinámicamente en tiempo de ejecución. Las funciones anónimas pueden aceptar entradas y devolver salidas, al igual que las funciones estándar. Una función anónima generalmente no es accesible después de su creación inicial.

A las variables se les puede asignar una función anónima. Tal expresión se llamafunction expression.

A continuación se muestra la sintaxis de la función anónima.

var res = function( [arguments] ) { ... }

Example − Anonymous Function

var f = function(){ return "hello"} 
console.log(f())

La siguiente salida se muestra en la ejecución exitosa del código anterior.

hello

Example − Anonymous Parameterized Function

var func = function(x,y){ return x*y }; 
function product() { 
   var result; 
   result = func(10,20); 
   console.log("The product : "+result) 
} 
product()

La siguiente salida se muestra en la ejecución exitosa del código anterior.

The product : 200

El constructor de funciones

La declaración de función no es la única forma de definir una nueva función; puede definir su función dinámicamente usando el constructor Function () junto con el operador new.

A continuación se muestra la sintaxis para crear una función usando el constructor Function () junto con el operador new.

var variablename = new Function(Arg1, Arg2..., "Function Body");

El constructor Function () espera cualquier número de argumentos de cadena. El último argumento es el cuerpo de la función: puede contener declaraciones de JavaScript arbitrarias, separadas entre sí por punto y coma.

Al constructor de Function () no se le pasa ningún argumento que especifique un nombre para la función que crea.

Example − Function Constructor

var func = new Function("x", "y", "return x*y;"); 
function product() { 
   var result; 
   result = func(10,20); 
   console.log("The product : "+result)
} 
product()

En el ejemplo anterior, el constructor Function () se usa para definir una función anónima. La función acepta dos parámetros y devuelve su producto.

La siguiente salida se muestra en la ejecución exitosa del código anterior.

The product : 200

Funciones de recursividad y JavaScript

La recursividad es una técnica para iterar sobre una operación haciendo que una función se llame a sí misma repetidamente hasta que llegue a un resultado. La recursividad se aplica mejor cuando necesita llamar a la misma función repetidamente con diferentes parámetros dentro de un bucle.

Example − Recursion

function factorial(num) { 
   if(num <= 0) { 
      return 1; 
   } else { 
      return (num * factorial(num-1)  ) 
   } 
} 
console.log(factorial(6))

En el ejemplo anterior, la función se llama a sí misma. La siguiente salida se muestra en la ejecución exitosa del código anterior.

720

Example − Anonymous Recursive Function

(function() { 
   var msg = "Hello World" 
   console.log(msg)
})()

La función se llama a sí misma usando un par de paréntesis (). La siguiente salida se muestra en la ejecución exitosa del código anterior.

Hello World

Funciones lambda

Lambda se refiere a funciones anónimas en programación. Las funciones Lambda son un mecanismo conciso para representar funciones anónimas. Estas funciones también se denominanArrow functions.

Función Lambda - Anatomía

Hay 3 partes en una función Lambda:

  • Parameters - Una función puede tener opcionalmente parámetros.

  • los fat arrow notation/lambda notation (=>): También se llama como el operador va a.

  • Statements - Representa el conjunto de instrucciones de la función.

Tip - Por convención, se recomienda el uso de un parámetro de una sola letra para una declaración de función compacta y precisa.

Expresión Lambda

Es una expresión de función anónima que apunta a una sola línea de código. A continuación se muestra la sintaxis de la misma.

([param1, parma2,…param n] )=>statement;

Example − Lambda Expression

var foo = (x)=>10+x 
console.log(foo(10))

El ejemplo declara una función de expresión lambda. La función devuelve la suma de 10 y se pasa el argumento.

La siguiente salida se muestra en la ejecución exitosa del código anterior.

20

Declaración Lambda

Es una declaración de función anónima que apunta a un bloque de código. Esta sintaxis se utiliza cuando el cuerpo de la función abarca varias líneas. A continuación se muestra la sintaxis del mismo.

( [param1, parma2,…param n] )=> {       
   //code block 
}

Example − Lambda Statement

var msg = ()=> { 
   console.log("function invoked") 
} 
msg()

La referencia de la función se devuelve y se almacena en la variable msg. La siguiente salida se muestra en la ejecución exitosa del código anterior.

function  invoked

Variaciones sintácticas

Paréntesis opcionales para un solo parámetro.

var msg = x=> { 
   console.log(x) 
} 
msg(10)

Tirantes opcionales para una sola declaración. Paréntesis vacíos para ningún parámetro.

var disp = ()=>console.log("Hello World") 
disp();

Expresión de función y declaración de función

La expresión de función y la declaración de función no son sinónimos. A diferencia de una expresión de función, una declaración de función está vinculada por el nombre de la función.

La diferencia fundamental entre los dos es que las declaraciones de función se analizan antes de su ejecución. Por otro lado, las expresiones de función se analizan solo cuando el motor de secuencia de comandos las encuentra durante una ejecución.

Cuando el analizador de JavaScript ve una función en el flujo de código principal, asume la declaración de función. Cuando una función forma parte de una declaración, es una expresión de función.

Función de elevación

Al igual que las variables, las funciones también se pueden elevar. A diferencia de las variables, las declaraciones de funciones cuando se elevan, elevan la definición de la función en lugar de simplemente elevar el nombre de la función.

El siguiente fragmento de código ilustra la función de elevación en JavaScript.

hoist_function();  
function hoist_function() { 
   console.log("foo"); 
}

La siguiente salida se muestra en la ejecución exitosa del código anterior.

foo

Sin embargo, las expresiones de función no se pueden elevar. El siguiente fragmento de código ilustra lo mismo.

hoist_function(); // TypeError: hoist_function() is not a function  
var hoist_function() = function() { 
   console.log("bar"); 
};

Expresión de función inmediatamente invocada

Las expresiones de función invocadas inmediatamente (IIFE) se pueden utilizar para evitar el izado de variables desde dentro de los bloques. Permite el acceso público a los métodos conservando la privacidad de las variables definidas dentro de la función. Este patrón se denomina función anónima autoejecutable. Los dos ejemplos siguientes explican mejor este concepto.

Ejemplo 1: IIFE

var main = function() { 
   var loop = function() { 
      for(var x = 0;x<5;x++) {
         console.log(x); 
      } 
   }(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();

Ejemplo 2: IIFE

var main = function() { 
   (function() { 
      for(var x = 0;x<5;x++) { 
         console.log(x); 
      } 
   })(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();

Ambos ejemplos generarán la siguiente salida.

0 
1 
2 
3 
4 
Uncaught ReferenceError: x is not define

Funciones del generador

Cuando se invoca una función normal, el control descansa con la función llamada hasta que regresa. Con generadores en ES6, la función de llamada ahora puede controlar la ejecución de una función llamada. Un generador es como una función regular, excepto que:

  • La función puede devolver el control a la persona que llama en cualquier momento.

  • Cuando llamas a un generador, no funciona de inmediato. En cambio, obtienes un iterador. La función se ejecuta cuando llamas al siguiente método del iterador.

Los generadores se indican añadiendo un asterisco a la palabra clave de función como sufijo; de lo contrario, su sintaxis es idéntica a las funciones regulares.

El siguiente ejemplo ilustra lo mismo.

"use strict" 
function* rainbow() { 
   // the asterisk marks this as a generator 
   yield 'red'; 
   yield 'orange'; 
   yield 'yellow'; 
   yield 'green'; 
   yield 'blue'; 
   yield 'indigo'; 
   yield 'violet'; 
} 
for(let color of rainbow()) { 
   console.log(color); 
}

Los generadores permiten la comunicación bidireccional entre la persona que llama y la función llamada. Esto se logra utilizando elyield palabra clave.

Considere el siguiente ejemplo:

function* ask() { 
   const name = yield "What is your name?"; 
   const sport = yield "What is your favorite sport?"; 
   return `${name}'s favorite sport is ${sport}`; 
}  
const it = ask(); 
console.log(it.next()); 
console.log(it.next('Ethan'));  
console.log(it.next('Cricket'));

La secuencia de la función del generador es la siguiente:

  • El generador arrancó en pausa declaró; se devuelve el iterador.

  • El it.next () da como resultado "¿Cuál es su nombre". El generador está en pausa. Esto se hace mediante la palabra clave yield.

  • La llamada it.next ("Ethan") asigna el valor Ethan al nombre de la variable y da como resultado "¿Cuál es tu deporte favorito?" De nuevo, el generador está en pausa.

  • La llamada it.next ("Cricket") asigna el valor Cricket a la variable deporte y ejecuta la declaración de devolución posterior.

Por lo tanto, la salida del código anterior será:

{ 
   value: 'What is your name?', done: false 
} 
{ 
   value: 'What is your favorite sport?', done: false 
} 
{ 
   value: 'Ethan\'s favorite sport is Cricket', done: true 
}

Note - Las funciones del generador no se pueden representar mediante funciones de flecha.

Funciones de flecha

Las funciones de flecha que se introducen en ES ayudan a escribir las funciones en JavaScript de manera concisa. Aprendamos ahora sobre el mismo en detalle.

Funciones ES5 y anónimas

JavaScript hace un uso intensivo de anonymous functions. Una función anónima es una función que no tiene un nombre adjunto. Las funciones anónimas se utilizan durantefunction callback. El siguiente ejemplo ilustra el uso de una función anónima en ES5:

<script>
   setTimeout(function(){
      console.log('Learning at TutorialsPoint is fun!!')
   },1000)
</script>

El ejemplo anterior pasa una función anónima como parámetro a la predefinida setTimeout() function. La función setTimeout () devolverá la llamada a la función anónima después de 1 segundo.

La siguiente salida se muestra después de 1 segundo:

Learning at TutorialsPoint is fun!!

Sintaxis de la función de flecha

ES6 introduce el concepto de arrow function para simplificar el uso de anonymous function. Hay 3 partes en una función de flecha que son las siguientes:

  • Parameters - Una función de flecha puede tener opcionalmente parámetros

  • The fat arrow notation (=>) - También se llama como el operador va al

  • Statements - Representa el conjunto de instrucciones de la función.

Tip - Por convención, se recomienda el uso de un parámetro de una sola letra para una declaración de función de flecha compacta y precisa.

Sintaxis

//Arrow function that points to a single line of code
()=>some_expression

O

//Arrow function that points to a block of code
()=> { //some statements }`

O

//Arrow function with parameters
(param1,param2)=>{//some statement}

Ejemplo: función de flecha en ES6

El siguiente ejemplo define dos expresiones de función add y isEven usando la función de flecha

<script>
   const add = (n1,n2) => n1+n2
   console.log(add(10,20))

   const isEven = (n1) => {
      if(n1%2 == 0)
         return true;
      else
         return false;
   }
   console.log(isEven(10))
</script>

La salida del código anterior será la que se menciona a continuación:

30
true

Array.prototype.map () y función de flecha

En el siguiente ejemplo, se pasa una función de flecha como parámetro al Array.prototype.map() function.La función map () ejecuta la función de flecha para cada elemento de la matriz. En este caso, la función de flecha muestra cada elemento de la matriz y su índice.

<script>
   const names = ['TutorialsPoint','Mohtashim','Bhargavi','Raja']
   names.map((element,index)=> {
      console.log('inside arrow function')
      console.log('index is '+index+' element value is :'+element)
   })
</script>

La salida del código anterior será como se indica a continuación:

inside arrow function
index is 0 element value is :TutorialsPoint
inside arrow function
index is 1 element value is :Mohtashim
inside arrow function
index is 2 element value is :Bhargavi
inside arrow function
index is 3 element value is :Raja

Ejemplo: window.setTimeout () y función de flecha

El siguiente ejemplo pasa una función de flecha como parámetro a la predefinida setTimeout() function. lossetTimeout() La función devolverá la llamada a la función de flecha después de 1 segundo.

<script>
   setTimeout(()=>{
      console.log('Learning at TutorialsPoint is fun!!')
   },1000)
</script>

La siguiente salida se muestra después de 1 segundo:

Learning at TutorialsPoint is fun!!

Función de flecha y "esto"

Dentro de una función de flecha si usamos this pointer, apuntará al ámbito léxico adjunto. Esto significa que las funciones de flecha no crean un nuevothis pointerinstancia cada vez que se invoca. Las funciones de flecha hacen uso de su alcance adjunto. Para entender esto, veamos un ejemplo.

<script>
   //constructor function
   function Student(rollno,firstName,lastName) {
      this.rollno = rollno;
      this.firstName = firstName;
      this.lastName = lastName;
      this.fullNameUsingAnonymous = function(){
         setTimeout(function(){
            //creates a new instance of this ,hides outer scope of this
            console.log(this.firstName+ " "+this.lastName)
         },2000)
      }
      this.fullNameUsingArrow = function(){
         setTimeout(()=>{
            //uses this instance of outer scope
            console.log(this.firstName+ " "+this.lastName)
         },3000)
      }
   }
   const s1 = new Student(101,'Mohammad','Mohtashim')
   s1.fullNameUsingAnonymous();
   s1.fullNameUsingArrow();
</script>

Cuando se usa una función anónima con setTimeout(), la función se invoca después de 2000 milisegundos. Una nueva instancia de“this”se crea y sombrea la instancia de la función Student. Entonces, el valor dethis.firstName y this.lastName estarán undefined. La función no usa el alcance léxico o el contexto de ejecución actual. Este problema se puede resolver utilizando unarrow function.

La salida del código anterior será la siguiente:

undefined undefined
Mohammad Mohtashim