Skip to content

Latest commit

 

History

History
665 lines (460 loc) · 10.4 KB

File metadata and controls

665 lines (460 loc) · 10.4 KB
theme black
highlightTheme github-dark

Javascript - le basi


Const

Il valore di una costante non può essere modificato

const invariabile = 5;
invariabile = 6; // NO! 
// TypeError: Assignment to constant variable.

--

Const

Se la costante è un oggetto o un array, le sue proprietà o i suoi elementi possono essere modificati!

const nomeCostante = {}; // Oggetto

nomeCostante.proprieta = 1; // OK: 
// ho modificato una proprietà dell'oggetto, 
// ma non l'oggetto in sè

--

Let

Può cambiare nel tempo

let nomeLet = "valore";

nomeLet = {
  proprieta: "valore",
  altra: 123
};

Si può fare, ma è sconsigliato modificare il tipo di dato di una variabile!

--

Var

Sintassi valida ma non più in uso

var nomeVariabile = "valore";

al suo posto, utilizza const e let


Oggetti

const myObject = {
  proprieta1: "valore",
  proprieta2: "altro valore"
};

Accedere al valore di una proprietà:

// sintassi equivalenti
const proprieta1 = myObject["proprieta1"];

const proprieta2 = myObject.proprieta2;

--

{Destructuring}

Estrae una o più proprietà di un oggetto e le assegna a delle variabili

const { inputPath, url, postId, tags, ...postContent } = apiPost;

Approfondisci su MDN

--

...Spread

const oldObject = {
  "key1": "first value",
  "key2": "second value",
  "key3": "third value"
};

const myObject = {
  "key0": "zeroth value",
  ...oldObject
};

// > myObject: Object { key0: "zeroth value", key1: "first value", key2: "second value", key3: "third value" }

Approfondisci su MDN

--

Funzione Object.entries()

const utente = { nome: "Mario", cognome: "Rossi" };

const proprietaUtente = Object.entries(utente);

/*
proprietaUtente = [
  ["nome", "Mario"],
  ["cognome", "Rossi"]
]
*/

Genera un array di coppie chiave/valore

--

Esempio di utilizzo di Object.entries()

const utente = { nome: "Mario", cognome: "Rossi" };

Object.entries(utente).forEach(([chiave, valore]) => {
  // esegue qualcosa su ciascuna coppia chiave/valore dell'oggetto
  console.log("- ", chiave, " -> ", valore);
});

/*
- nome -> Mario
- cognome -> Rossi
*/

Array

const myArray = [
  "stringa", 
  123, 
  true, 
  { "proprietàOggetto": "valore" }, 
  ["array"]
];

--

Accedere al valore in una determinata posizione:

const primoElementoDellArray = myArray[0]; // "stringa"
const secondoElementoDellArray = myArray[1]; // 123

--

[Destructuring]

Estrae uno o più elementi di un array e li assegna a variabili

const myArray = ["stringa", 2, 3];

// destructuring
const [primo, secondo, terzo] = myArray;

// > primo === "stringa"; 
// > secondo === 2; 
// > terzo === 3

(puoi nominare liberamente le variabili)

--

[Destructuring]

const myArray = ["stringa", "secondo", 3];

// non devi per forza estrarre tutti gli elementi
const [primo, , terzo] = myArray;

// > primo === "stringa"; terzo === 3

--

...Spread

const myArray = [ 4, 5, 6 ];
const myMergedArray = [ 1, 2, 3, ...myArray ];

// > Array(6) [ 1, 2, 3, 4, 5, 6 ]

--

...Spread

function concatStrings(...args) {
  return args.join(' ');
}

concatStrings("Hello", "world")

--

Metodi degli array

forEach(callback)

myArray.forEach((el) => {
  el = el + "stringa";
});

myArray === myArray;
// vengono modificati gli elementi contenuti nell'array
// non l'array in sè

Modifica ogni elemento dell'array, applicando la funzione di callback

--

Metodi degli array

map(callback)

const newArray = myArray.map((el) => {
  el = el + "stringa";
  return el;
})

newArray !== myArray;
// il metodo map() genera un nuovo array

Ritorna un nuovo array, con gli elementi modificati dalla callback

--

Altri metodi degli array

  • Sort: riordina gli elementi dell’array
  • Find: trova un elemento
  • Filter: elimina alcuni elementi
  • Reduce: elabora tutti gli elementi in un unico risultato
  • Join: unisce due o più array

--

Approfondisci

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration


Funzioni

const miaFunzione = function nomeFunzione() {
  //...
}

const miaArrowFunction = () => {
  //...
}

const funzioneConParametri = (param1, param2) => {
  return param1 + " " + param2;
}

--

First class functions

Si può assegnare una funzione a una variabile

const foo = () => {
  console.log("foobar");
};
foo();

--

First class functions

Si può passare una funzione come argomento di un'altra funzione

function eseguiOperazione(operazione, a, b) {
  return operazione(a, b);
}

function somma(a, b) {
  return a + b;
}

eseguiOperazione(somma, 5, 3); // Restituisce 8

--

First class functions

Una funzione può ritornare una nuova funzione

function creaFunzioneGreeting(saluto) {
  return function(nome) {
    return `${saluto}, ${nome}!`;
  };
}

const salutaInItaliano = creaFunzioneGreeting("Ciao");
salutaInItaliano("Marco"); // Restituisce "Ciao, Marco!"

--

First class functions

Le funzioni possono avere proprietà e metodi come gli altri oggetti

function test() {}
test.descrizione = "Questa è una proprietà della funzione 'test'";

--

Approfondisci

https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function

--

Currying

Funzioni che ritornano altre funzioni, con una sintassi fluida

const chiama = (nome) => (functionCognome) => {
  return nome + " " + cognome;
}

// posso chiamarla così:
chiama("Mario")("Bianchi");

// oppure in più step, 
// assegnando a una variabile la funzione generata:
const chiamaPaolo = chiama("Paolo");
chiamaPaolo("Rossi"); 

--

Approfondisci

https://it.javascript.info/currying-partials


Funzioni asincrone

--

function saluta() {
  setTimeout(() => {
    console.log("Ciao");
  }, 1000);
}

const chiama = (nome) => {
  setTimeout(() => {
    console.log("Ehi, " + nome + "!");
  }, 0); // timeout = zero
}

console.log("Inizio");
saluta();
chiama("Mario");
console.log("Fine");

/* Output:
Inizio
Fine
Ehi, Mario!
Ciao
*/

--

Approfondisci

/i/https://youtu.be/N0Au8yc5IOw?si=T0TvfQ-4fFJJL1Gi

JavaScript Event Loop

--

Come posso controllare l'ordine di esecuzione delle funzioni asincrone?

--

Callback

function saluta(cb) {
  setTimeout(() => {
    console.log("Ciao");
    cb(); // <- esegue la callback
  }, 1000);
}

const chiama = (nome) => {
  setTimeout(() => {
    console.log("Ehi, " + nome + "!");
  }, 0);
}

saluta(() => chiama("Paolo"));

/* Output:
Ciao
Ehi, Paolo!
*/

--

Attenzione

La funzione chiama() si aspetta un parametro.

Poiché la funzione saluta() non passa nessun parametro alla callback,
chiama("Paolo") viene eseguita in una callback che non ha parametri!

saluta( function cb(/* nessun parametro */) { chiama("Paolo") } );

--

Promise

  • è un oggetto che rappresenta un'operazione asincrona
  • ha 3 metodi:
    • then(fn) -> esegue fn() come callback in caso di success
    • catch(fn) -> esegue fn() in caso di errore
    • finally(fn) -> esegue fn() in entrambi i casi

--

Promise: vantaggi

  • permette di concatenare molte funzioni asincrone una dopo l'altra, invece che una dentro l'altra, come avveniva con le callback
  • permette di gestire gli errori in modo standardizzato

--

Promise: come si costruisce

function saluta() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Ciao");
      resolve();
    }, 1000);
  });
}

const chiama = (nome) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Ehi, " + nome + "!");
      resolve();
    }, 0); 
  });
}

--

Promise: come si usa

saluta()
  .then(() => chiama("Paolo"))
  .then(saluta)
  .then(() => { console.log("Fine") });

/* Output:
Ciao
Ehi, Paolo!
Ciao
Fine
*/

--

Promise: come si gestiscono gli errori

saluta()
  .then(() => chiama("Paolo"))
  .then(() => { throw new Error("Ops, qualcosa è andato storto") })
  .then(saluta)
  .then(() => { console.log("Fine") })
  .catch((err) => console.error(err.message));

/* Output:
Ciao
Ehi, Paolo!
Ops, qualcosa è andato storto
*/

--

Approfondisci

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

--

Async/await

E' una sintassi ancora più comoda per scrivere ed eseguire Promise

--

Async/await

async function saluta() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Ciao");
      resolve();
    }, 1000);
  });
}

const chiama = async (nome) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log("Ehi, " + nome + "!");
      resolve();
    }, 0); 
  });
}

const main = async () => {
  console.log("Inizio");
  await saluta();
  await chiama("Paolo");
  console.log("Fine");
}

main();

/* Output:
Inizio
Ciao
Ehi, Paolo!
Fine
*/

--

Async/await: come si gestiscono gli errori

try {
  main();
} catch(err) {
  console.error(err);
}

...come se si trattasse di codice sincrono


Mapping con funzioni asincrone

--

Problema: abbiamo un array da mappare su una funzione asincrona

const result = [1, 2, 3, 4].map(async (id) => {
  return await getById(id);
})

--

Questa funzione ritorna:

[Promise, Promise, Promise, Promise]

mentre ci aspettavamo:

["valuea", "value2", "value3", "value4"]

--

Soluzione: Promise.all()

const result = Promise.all(
  [1, 2, 3, 4].map(async (id) => {
    return await getById(id);
  })
);

--

Approfondisci su MDN