8. Le funzioni

8.1. script [func-01]
Lo script si concentra sulla modalità di passaggio dei parametri di una funzione:
- passaggio per valore per numeri, stringhe e valori booleani;
- passaggio per riferimento per array, oggetti letterali e funzioni;
'use strict';
// modalità di passaggio dei parametri di una funzione
// -----------------------numero - passaggio per valore
function doSomethingWithNumber(param) {
param++;
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === count);
}
// codice di chiamata
let count = 10;
doSomethingWithNumber(count);
console.log("[count outside function]=", count);
// --------------------- stringa - passaggio per valore
function doSomethingWithString(param) {
param += " xyz"
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === text);
}
// codice di chiamata
let text = "abcd";
doSomethingWithString(text);
console.log("[text outside function]=", text);
// --------------------- booleano - passaggio per valore
function doSomethingWithBoolean(param) {
param = !param;
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === bool);
}
// codice di chiamata
let bool = true;
doSomethingWithBoolean(bool);
console.log("bool [outside function]=", bool);
// --------------------- array - passaggio per riferimento
function doSomethingWithArray(param) {
param.push(1000);
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === tab);
}
// codice di chiamata
const tab = [10, 20, 30];
doSomethingWithArray(tab);
console.log("[tab outside function]=", tab);
// --------------------- oggetto - passaggio per riferimento
function doSomethingWithObject(param) {
param.unePropriétéNouvelle = "xyz";
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === obj);
}
// codice di chiamata
const obj = [10, 20, 30];
doSomethingWithObject(obj);
console.log("[obj outside function]=", obj);
// --------------------- funzione - passaggio per riferimento
function doSomethingWithFunction(param) {
// una cosa piuttosto strana che però funziona
param.unePropriétéNouvelle = "xyz";
console.log("[param inside function]=", param, "[type]=", typeof (param), "[passage par référence]=", param === f);
}
// codice di chiamata
const f = x => x + 4;
doSomethingWithFunction(f);
console.log("[f outside function]=", f, f.unePropriétéNouvelle, typeof (f));
Esecuzione
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-01.js"
[param inside function]= 11 [type]= number [passage par référence]= false
[count outside function]= 10
[param inside function]= abcd xyz [type]= string [passage par référence]= false
[text outside function]= abcd
[param inside function]= false [type]= boolean [passage par référence]= false
bool [outside function]= true
[param inside function]= [ 10, 20, 30, 1000 ] [type]= object [passage par référence]= true
[tab outside function]= [ 10, 20, 30, 1000 ]
[param inside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ] [type]= object [passage par référence]= true
[obj outside function]= [ 10, 20, 30, 'unePropriétéNouvelle': 'xyz' ]
[param inside function]= x => x + 4 [type]= function [passage par référence]= true
[f outside function]= x => x + 4 xyz function
8.2. script [func-02]
Lo script seguente mostra che il tipo [function] è un tipo di dati come un altro e che una variabile può avere questo tipo. Mostra inoltre due modi per definire una funzione:
- uno con la parola chiave [function];
- l’altro con la notazione «freccia» =>;
''use strict';
// è possibile assegnare una funzione a una variabile
const variable1 = function (a, b) {
return a + b;
};
console.log("typeof(variable1)=", typeof (variable1));
// la variabile può quindi essere utilizzata come una funzione
console.log("variable1(10,12)=", variable1(10, 12));
// la definizione della funzione può essere effettuata con la notazione =>
const variable2 = (a, b, c) => {
return a - b + c;
};
console.log("variable2(10,12,14)=", variable2(10, 12, 14));
// è possibile omettere le parentesi graffe se nel codice della funzione è presente una sola espressione
// tale espressione costituisce quindi il valore di ritorno della funzione
const variable3 = (a, b, c) => a + b + c;
console.log("variable3(10,12,14)=", variable3(10, 12, 14));
Esecuzione
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-02.js"
typeof(variable1)= function
variable1(10,12)= 22
variable2(10,12,14)= 12
variable3(10,12,14)= 36
8.3. script [func-03]
Questo script illustra la possibilità di passare una funzione come parametro a un’altra funzione. Questa tecnica è ampiamente utilizzata nei framework JavaScript.
'use strict';
// i parametri di una funzione possono essere di tipo [fonction]
// funzione f1
function f1(param1, param2) {
return param1 + param2 + 10;
}
// funzione f2
function f2(param1, param2) {
return param1 + param2 + 20;
}
// funzione g con la funzione f come parametro
function g(param1, param2, f) {
return f(param1, param2) + 100;
}
// utilizzi di g
console.log(g(0, 10, f1));
console.log(g(0, 10, f2));
// il parametro effettivo di tipo funzione può essere passato direttamente - forma 1
console.log(g(0, 10, (param1, param2) => {
return param1 + param2 + 30;
}));
// il parametro effettivo di tipo funzione può essere passato direttamente - forma 2
console.log(g(0, 10, function (param1, param2) {
return param1 + param2 + 40;
}));
Esecuzione
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\fonctions\func-03.js"
120
130
140
150
8.4. script [func-04]
Lo script seguente mostra che una funzione JavaScript può comportarsi come una classe:
'use strict';
// una funzione può essere utilizzata come oggetto
// un guscio vuoto
function f() {
}
// a cui vengono assegnate proprietà dall'esterno
f.prop1 = "val1";
f.show = function () {
console.log(this.prop1);
}
// uso di f
f.show();
// una funzione g che funziona come una classe
function g() {
this.prop2 = "val2";
this.show = function () {
console.log(this.prop2);
}
}
// istanziazione della funzione con [new]
new g().show();
Commenti
- righe 5-7: il corpo della funzione f non definisce alcuna proprietà;
- righe 9-12: si assegnano proprietà alla funzione f dall’esterno;
- riga 14: utilizzo della funzione (oggetto) f. Si noti che non si scrive [f()] ma semplicemente [f]. Si tratta della notazione di un oggetto;
- righe 17-22: si definisce una funzione [g] come se fosse una classe con proprietà e metodi;
- riga 24: la funzione [g] viene istanziata da [new g()];
Risultati dell’esecuzione
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2
ES6 ha introdotto il concetto di classe, che ora ci permette di evitare di ricorrere alle funzioni per ottenere delle classi.
8.5. script [func-05]
Lo script [func-05] mostra l’uso di un operatore denominato [rest operator]:
'use strict';
// operatore resto
function f(arg1, ...otherArgs) {
// primo argomento
console.log("arg1=", arg1);
// gli altri argomenti
let i = 0;
otherArgs.forEach(element => {
console.log("otherArguments[", i, "]=", element);
i++;
});
}
// chiamata
f(1, "deux", "trois", { x: 2, y: 3 })
- riga 3: la notazione [...otherArgs] fa sì che con una chiamata del tipo f(param1, param2, param3) si ottenga la riga 3:
- arg1=param1
- otherArgs=[param2, param3]. [otherArgs] è quindi un array che raccoglie tutti i parametri effettivi passati dopo [param1];
I risultati dell’applicazione sono i seguenti: