ES6 - Funzioni

Functionssono gli elementi costitutivi del codice leggibile, gestibile e riutilizzabile. Le funzioni vengono definite utilizzando la parola chiave function. Di seguito è riportata la sintassi per definire una funzione standard.

function function_name() { 
   // function body 
}

Per forzare l'esecuzione della funzione, deve essere chiamata. Questo è chiamato come chiamata di funzione. La seguente è la sintassi per invocare una funzione.

function_name()

Esempio: definizione di funzione semplice

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

L'esempio definisce una funzione test (). Una coppia di delimitatori ({}) definiscono il corpo della funzione. È anche chiamato comefunction scope. Una funzione deve essere invocata per forzarne l'esecuzione.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

function called

Classificazione delle funzioni

Le funzioni possono essere classificate come Returning e Parameterized funzioni.

Restituzione di funzioni

Le funzioni possono anche restituire il valore insieme al controllo al chiamante. Tali funzioni sono chiamate come funzioni di ritorno.

Di seguito è riportata la sintassi per la funzione di ritorno.

function function_name() { 
   //statements 
   return value; 
}
  • Una funzione restituita deve terminare con un'istruzione return.

  • Una funzione può restituire al massimo un valore. In altre parole, può esserci solo un'istruzione return per funzione.

  • L'istruzione return dovrebbe essere l'ultima istruzione nella funzione.

Il frammento di codice seguente è un esempio di una funzione restituita:

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

L'esempio sopra definisce una funzione che restituisce la stringa "ciao mondo !!!" al chiamante. Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

hello world!!!

Funzioni parametrizzate

I parametri sono un meccanismo per passare valori alle funzioni. I parametri fanno parte della firma della funzione. I valori dei parametri vengono passati alla funzione durante la sua chiamata. Se non diversamente specificato, il numero di valori passati a una funzione deve corrispondere al numero di parametri definiti.

Di seguito è riportata la sintassi che definisce una funzione parametrizzata.

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

Example − Parameterized Function

L'esempio definisce una funzione add che accetta due parametri n1 e n2e stampa la loro somma. I valori dei parametri vengono passati alla funzione quando viene richiamata.

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

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

The sum of the values entered 25

Parametri di funzione predefiniti

In ES6, una funzione consente di inizializzare i parametri con valori predefiniti, se non vengono passati valori o se non è definita. Lo stesso è illustrato nel codice seguente.

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

La funzione sopra, imposta il valore di b su 1 per impostazione predefinita. La funzione considererà sempre il parametro b per portare il valore 1 a meno che un valore non sia stato passato esplicitamente. Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

5

Il valore predefinito del parametro verrà sovrascritto se la funzione passa un valore in modo esplicito.

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

Il codice precedente imposta il valore del parametro b esplicitamente su 2, sovrascrivendo così il suo valore predefinito. Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

6

Per una migliore comprensione, consideriamo l'esempio seguente.

Esempio 1

L'esempio seguente mostra una funzione che accetta due parametri e restituisce la loro somma. Il secondo parametro ha un valore predefinito di 10. Ciò significa che, se non viene passato alcun valore al secondo parametro, il suo valore sarà 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>

L'output del codice sopra sarà come indicato di seguito -

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

Esempio 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>

L'output del codice sopra sarà come mostrato di seguito -

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

Parametri di riposo

I parametri di riposo sono simili agli argomenti delle variabili in Java. I parametri di riposo non limitano il numero di valori che puoi passare a una funzione. Tuttavia, i valori passati devono essere tutti dello stesso tipo. In altre parole, i parametri rest agiscono come segnaposto per più argomenti dello stesso tipo.

Per dichiarare un parametro rest, il nome del parametro è preceduto da tre punti, noti come operatore spread. Il seguente esempio illustra lo stesso.

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

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

0 
1 
3

Note - I parametri di riposo dovrebbero essere gli ultimi nell'elenco dei parametri di una funzione.

Funzione anonima

Le funzioni che non sono associate a un identificatore (nome della funzione) vengono chiamate come funzioni anonime. Queste funzioni vengono dichiarate dinamicamente in fase di esecuzione. Le funzioni anonime possono accettare input e restituire output, proprio come fanno le funzioni standard. Una funzione anonima di solito non è accessibile dopo la sua creazione iniziale.

Alle variabili può essere assegnata una funzione anonima. Tale espressione è chiamata afunction expression.

Di seguito è riportata la sintassi per la funzione anonima.

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

Example − Anonymous Function

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

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

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()

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

The product : 200

Il costruttore di funzioni

L'istruzione di funzione non è l'unico modo per definire una nuova funzione; puoi definire la tua funzione dinamicamente usando il costruttore Function () insieme al nuovo operatore.

Di seguito è riportata la sintassi per creare una funzione utilizzando il costruttore Function () insieme al nuovo operatore.

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

Il costruttore Function () si aspetta un numero qualsiasi di argomenti stringa. L'ultimo argomento è il corpo della funzione: può contenere istruzioni JavaScript arbitrarie, separate l'una dall'altra da punto e virgola.

Al costruttore Function () non viene passato alcun argomento che specifichi un nome per la funzione che 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()

Nell'esempio precedente, il costruttore Function () viene utilizzato per definire una funzione anonima. La funzione accetta due parametri e restituisce il loro prodotto.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

The product : 200

Ricorsione e funzioni JavaScript

La ricorsione è una tecnica per iterare su un'operazione facendo chiamare ripetutamente a se stessa una funzione finché non arriva a un risultato. La ricorsione viene applicata al meglio quando è necessario chiamare ripetutamente la stessa funzione con parametri diversi dall'interno di un ciclo.

Example − Recursion

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

Nell'esempio sopra la funzione chiama se stessa. Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

720

Example − Anonymous Recursive Function

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

La funzione chiama se stessa usando una coppia di parentesi (). Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

Hello World

Funzioni Lambda

Lambda si riferisce a funzioni anonime nella programmazione. Le funzioni Lambda sono un meccanismo conciso per rappresentare funzioni anonime. Queste funzioni sono anche chiamate comeArrow functions.

Funzione Lambda - Anatomia

Ci sono 3 parti in una funzione Lambda:

  • Parameters - Una funzione può facoltativamente avere parametri.

  • Il fat arrow notation/lambda notation (=>): Viene anche chiamato come operatore va a.

  • Statements - Rappresenta il set di istruzioni della funzione.

Tip - Per convenzione, l'uso di un parametro a lettera singola è incoraggiato per una dichiarazione di funzione compatta e precisa.

Espressione lambda

È un'espressione di funzione anonima che punta a una singola riga di codice. Di seguito è riportata la sintassi per lo stesso.

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

Example − Lambda Expression

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

L'esempio dichiara una funzione di espressione lambda. La funzione restituisce la somma di 10 e l'argomento passato.

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

20

Istruzione Lambda

È una dichiarazione di funzione anonima che punta a un blocco di codice. Questa sintassi viene utilizzata quando il corpo della funzione si estende su più righe. Di seguito è riportata la sintassi dello stesso.

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

Example − Lambda Statement

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

Il riferimento della funzione viene restituito e memorizzato nella variabile msg. Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

function  invoked

Variazioni sintattiche

Parentesi opzionali per un singolo parametro.

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

Parentesi graffe opzionali per una singola istruzione. Parentesi vuote per nessun parametro.

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

Espressione di funzione e dichiarazione di funzione

L'espressione di funzione e la dichiarazione di funzione non sono sinonimi. A differenza di un'espressione di funzione, una dichiarazione di funzione è vincolata dal nome della funzione.

La differenza fondamentale tra i due è che le dichiarazioni di funzione vengono analizzate prima della loro esecuzione. D'altra parte, le espressioni di funzione vengono analizzate solo quando il motore di script le incontra durante un'esecuzione.

Quando il parser JavaScript vede una funzione nel flusso di codice principale, assume la dichiarazione della funzione. Quando una funzione si presenta come parte di un'istruzione, è un'espressione di funzione.

Funzione di sollevamento

Come le variabili, anche le funzioni possono essere sollevate. A differenza delle variabili, le dichiarazioni di funzione quando vengono sollevate, inviano la definizione della funzione anziché limitarsi a sollevare il nome della funzione.

Il seguente frammento di codice illustra il sollevamento di funzioni in JavaScript.

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

Il seguente output viene visualizzato in caso di corretta esecuzione del codice precedente.

foo

Tuttavia, le espressioni di funzione non possono essere sollevate. Il frammento di codice seguente illustra lo stesso.

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

Espressione di funzione richiamata immediatamente

Le espressioni di funzione immediatamente invocate (IIFE) possono essere utilizzate per evitare il sollevamento di variabili dall'interno dei blocchi. Consente l'accesso pubblico ai metodi mantenendo la privacy per le variabili definite all'interno della funzione. Questo modello viene chiamato come funzione anonima autoeseguente. I due esempi seguenti spiegano meglio questo concetto.

Esempio 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();

Esempio 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();

Entrambi gli esempi renderanno il seguente output.

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

Funzioni del generatore

Quando viene invocata una funzione normale, il controllo rimane con la funzione chiamata finché non ritorna. Con i generatori in ES6, la funzione chiamante può ora controllare l'esecuzione di una funzione chiamata. Un generatore è come una normale funzione tranne che:

  • La funzione può restituire il controllo al chiamante in qualsiasi momento.

  • Quando chiami un generatore, non funziona subito. Invece, ottieni indietro un iteratore. La funzione viene eseguita quando chiamate il metodo successivo dell'iteratore.

I generatori sono indicati aggiungendo un asterisco alla parola chiave function; altrimenti, la loro sintassi è identica alle funzioni normali.

Il seguente esempio illustra lo stesso.

"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); 
}

I generatori abilitano la comunicazione bidirezionale tra il chiamante e la funzione chiamata. Ciò si ottiene utilizzando ilyield parola chiave.

Considera il seguente esempio:

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 sequenza della funzione del generatore è la seguente:

  • Generatore avviato in pausa dichiarato; viene restituito l'iteratore.

  • Il it.next () restituisce "Qual è il tuo nome". Il generatore è in pausa. Questo viene fatto dalla parola chiave yield.

  • La chiamata it.next ("Ethan") assegna il valore Ethan al nome della variabile e restituisce "Qual è il tuo sport preferito?" Di nuovo il generatore è in pausa.

  • La chiamata it.next ("Cricket") assegna il valore Cricket alla variabile sport ed esegue la successiva istruzione return.

Quindi, l'output del codice sopra sarà -

{ 
   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 - Le funzioni del generatore non possono essere rappresentate utilizzando le funzioni freccia.

Funzioni freccia

Le funzioni freccia introdotte in ES aiutano a scrivere le funzioni in JavaScript in modo conciso. Vediamo ora di imparare lo stesso in dettaglio.

Funzioni ES5 e anonime

JavaScript fa un uso massiccio di anonymous functions. Una funzione anonima è una funzione a cui non è associato un nome. Le funzioni anonime vengono utilizzate durantefunction callback. Il seguente esempio illustra l'uso di una funzione anonima in ES5:

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

L'esempio precedente passa una funzione anonima come parametro al predefinito setTimeout() function. La funzione setTimeout () richiamerà la funzione anonima dopo 1 secondo.

Il seguente output viene mostrato dopo 1 secondo:

Learning at TutorialsPoint is fun!!

Sintassi della funzione freccia

ES6 introduce il concetto di arrow function per semplificare l'utilizzo di anonymous function. Ci sono 3 parti in una funzione freccia che sono le seguenti:

  • Parameters - Una funzione freccia può facoltativamente avere parametri

  • The fat arrow notation (=>) - Viene anche chiamato come operatore va a

  • Statements - Rappresenta il set di istruzioni della funzione

Tip - Per convenzione, l'uso di un parametro a singola lettera è incoraggiato per una dichiarazione di funzione freccia compatta e precisa.

Sintassi

//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}

Esempio: funzione freccia in ES6

L'esempio seguente definisce due espressioni di funzione add e isEven utilizzando la funzione freccia

<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>

L'output del codice sopra sarà come indicato di seguito -

30
true

Array.prototype.map () e funzione freccia

Nell'esempio seguente, una funzione freccia viene passata come parametro al file Array.prototype.map() function.La funzione map () esegue la funzione freccia per ogni elemento dell'array. La funzione freccia in questo caso mostra ogni elemento dell'array e il suo indice.

<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>

L'output del codice sopra sarà come indicato di seguito:

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

Esempio: window.setTimeout () e funzione freccia

L'esempio seguente passa una funzione freccia come parametro al file predefinito setTimeout() function. IlsetTimeout() funzione richiamerà la funzione freccia dopo 1 secondo.

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

Il seguente output viene mostrato dopo 1 secondo:

Learning at TutorialsPoint is fun!!

Funzione freccia e "questo"

All'interno di una funzione freccia se usiamo this pointer, punterà all'ambito lessicale allegato. Ciò significa che le funzioni freccia non ne creano un nuovothis pointeristanza ogni volta che viene invocato. Le funzioni freccia fanno uso del suo ambito di inclusione. Per capire questo, vediamo un esempio.

<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>

Quando viene utilizzata una funzione anonima con setTimeout(), la funzione viene richiamata dopo 2000 millisecondi. Una nuova istanza di“this”viene creato e ombreggia l'istanza della funzione Student. Quindi, il valore dithis.firstName e this.lastName sarà undefined. La funzione non utilizza l'ambito lessicale o il contesto dell'esecuzione corrente. Questo problema può essere risolto utilizzando un filearrow function.

L'output del codice precedente sarà il seguente:

undefined undefined
Mohammad Mohtashim