JavaScript per Sviluppatori Python (Parte 1)

Pubblicato da Michele Saba

Thumbnail Guida a JavaScript per sviluppatori Python parte 1

JavaScript e Python: linguaggi a confronto

In questa guida vi insegneremo tutte le basi necessarie a lavorare con JavaScript lato client, e faremo ciò in un format piuttosto originale rispetto alle altre guide sull'argomento, ovvero dalla prospettiva di un/a developer Python.

Il raffronto tra i due linguaggi è chiaramente uno stratagemma didattico pensato per rendere la guida più piacevole da seguire e per accorciare i tempi di apprendimento, fornendovi tutti gli strumenti necessari ad utilizzare JS da subito anche qualora non abbiate mai scritto una riga di codice in questo linguaggio. Analizzeremo inoltre le differenze tra i due, sottolineando quelle che appaiono essere le tante stranezze di JavaScript quando messo a confronto con Python.

La guida nasce come mini corso integrativo per gli studenti dei nostri corsi professionali Guida Pratica e Completa a Python, Django e Bootstrap e Guida per Sviluppatori a Django REST Framework e Vue JS.

Il primo può essere pensato come un bootcamp per chiunque intenda addentrarsi nell'affascinante mondo del web development con Python, partendo dalla creazione di una pagina HTML vuota per arrivare alla creazione di un sito web dinamico completo con uno dei web framework Python più usati, ovvero Django, passando per l'apprendimento di Python dalle basi in su. Il secondo, di livello più avanzato, si concentra sullo sviluppo di REST API con Python e Django e Single Page Application col framework frontend Vue JS. Le Single Page Application sono web app moderne e performanti, simili a quelle usate da Google per servizi come Gmail, da Instagram, Twitter, Spotify, YouTube ecc.

L'impiego di Vue JS rende quindi preferibile la conoscenza delle basi di JavaScript per poter seguire il corso al meglio, e questa guida è qui per questo.

Buona lettura!


Perché imparare JavaScript?

A chi si sta avvicinando da poco al mondo dello sviluppo software capiterà di sentire frasi del tipo "con JavaScript ci scrivi i siti web, con Python invece ci fai i programmi desktop, gli script e il machine learning" e di sentirsi un po' confusi quando si scopre che specularmente, anche con Python si possono fare siti e web app (basti pensare a Instagram o Spotify, entrambi scritti col web framework Python Django) e che anche con JavaScript si possono fare programmi desktop.

Ma insomma che succede? Perché dovreste imparare più di un linguaggio di programmazione se già ne conoscete uno che sembrerebbe essere più versatile di un coltellino svizzero? Le risposte possibili sono molteplici, ma per farla breve possiamo dire che semplicemente, vi conviene.

I linguaggi di programmazione nascono per molti motivi, e crescono soprattutto grazie alle community di developer che li usano. Si inizia a sperimentare e in breve tempo ecco che ad esempio, qualche azienda inizia ad adoperare i frutti di questi esperimenti in ambiente di produzione, facendo prove e migliorando l'ecosistema fino a creare tante alternative da cui poter scegliere per fare le stesse cose.

Ciò nonostante gli aspetti fondamentali dei vari linguaggi rimangono spesso gli stessi, rendendoli preferibili in alcuni contesti piuttosto che in altri, e dando vita a processi di sviluppo che vedono più di un linguaggio usato contemporaneamente per ottenere lo stesso risultato.

Questo può sembrare ovvio a chi è del settore, ma è meno intuitivo per chi ci si sta appena avvicinando: capita spesso che un progetto software utilizzi più linguaggi di programmazione! Ma restiamo nel mondo dello sviluppo web.

Quando sviluppiamo un sito con Python, il codice che utilizziamo gira all'interno del nostro server. Con JavaScript (abbreviato spesso come JS) abbiamo invece la possibilità di far girare codice lato client ottenendo dei vantaggi in termini di velocità e qualità dell'esperienza di navigazione per i nostri utenti.

Infatti JS è un linguaggio di scripting interpretato, e il suo codice sorgente può essere eseguito direttamente dal browser web.

Questo non significa che un linguaggio sia meglio dell'altro per quanto riguarda lo sviluppo web, piuttosto si tratta del fatto che i due linguaggi sono complementari. Il codice Python che gira nel server offre dei contenuti che possono essere utilizzati da client in cui gira JavaScript, come ad esempio qualsiasi browser web moderno per smartphone o desktop. La faccenda dovrebbe ora iniziare a farsi abbastanza chiara.

Questo tipo di approccio allo sviluppo web, con server e client comunicanti in maniera asincrona, sta diventando sempre più popolare perché permette di avere un framework front end JavaScript come ad esempio Vue.js sul lato client e avere poi sul server un linguaggio come Python, che rappresenta una buona scelta per la sua facilità di sviluppo, per la sua potenza e per la grande quantità di librerie open source disponibili.

Oltre a questo oggi è difficile trovare un sito web che non utilizzi JavaScript in qualche modo all'interno dell'interfaccia: basti pensare anche semplicemente a una libreria di componenti front end come può essere Bootstrap, in cui viene utilizzato JS per migliorare l'esperienza di navigazione degli utenti. Noi lo utilizzeremo principalmente all'interno dei browser per ottenere effetti dinamici e comunicare con le Web API.

Nel tempo sono uscite svariate versioni di JavaScript che hanno portato con sé aggiornamenti della sintassi e l'aggiunta di tante nuove funzionalità. Queste diverse versioni seguono uno standard chiamato ECMAscript, di cui JavaScript è senza dubbio l'implementazione più famosa.

P.S. precisiamo che JavaScript e Java hanno nomi simili ma non sono la stessa cosa!

Per chi è pensata questa guida?

Questa guida è pensata per sviluppatori Python che vogliono acquisire familiarità con JavaScript, e in particolare per sviluppatori web che utilizzano framework come Django, Flask o Fast API e si trovano a dover imparare JS rapidamente, magari per poter utilizzare framework come React, Angular o Vue.js.

Prerequisiti fondamentali della guida

Dal momento che l’intento principale di questa guida è fornire una mappa che permetta di velocizzare e massimizzare l'acquisizione del linguaggio JavaScript a chi già conosce Python, per seguire tutti i passaggi al meglio è necessario avere dei prerequisiti:

  • Una buona conoscenza delle basi della programmazione con Python e dei concetti fondamentali che rappresentano le basi del linguaggio: variabili, strutture di controllo, logica booleana, scope, tipi di dato, funzioni, classi, metodi…
  • Comprensione del concetto di programmazione a oggetti con Python.
  • Una conoscenza base di HTML e CSS, quindi una buona familiarità con la creazione e la personalizzazione di pagine web.
  • Aver sviluppato una certa capacità di effettuare ricerche e di approfondire temi in autonomia: in un corso rapido si può spiegare soltanto una certa quantità di concetti e per questo motivo vi lascerò comunque dei link di approfondimento.
  • Avere tanta voglia di imparare: all'interno di questo corso rapido andremo a esporre davvero tantissimi concetti.

Vi lascerò anche dei link ai miei corsi completi sullo sviluppo web con Python, Django REST framework e Vue.js che senza dare niente per scontato vi forniranno tutte le basi necessarie ad iniziare a creare siti web moderni e potenti con Python e Django.

Indice della guida

Questa guida è divisa in due parti e, come abbiamo detto, rappresenta un’introduzione a JavaScript per l’utilizzo nello sviluppo Front End: impareremo la sua sintassi e le sue funzionalità principali utilizzando Python come punto di riferimento. Gli argomenti che affronteremo mettendo a confronto JavaScript e Python sono i seguenti:

Nella seconda parte della guida passeremo alla scrittura del codice vero e proprio introducendo concetti nuovi e più avanzati.


Tipi di dato

In JavaScript abbiamo i seguenti tipi di dato:

  • Number: numeri interi o decimali.
  • BigInt: numeri interi di qualsiasi grandezza.
  • String: testo racchiuso tra apici singoli o doppi.
  • Boolean: i valori Vero o Falso.
  • Symbol: identificatore univoco e immutabile utilizzato principalmente per creare proprietà uniche negli oggetti
  • Null: un valore vuoto o nullo.
  • Undefined: una variabile non inizializzata.
  • Object: un oggetto generico che a sua volta comprende i tipi:
    • Object: un oggetto con proprietà e metodi
    • Function: rappresenta una funzione o una classe.
    • Array: collezione ordinata di valori.
    • Date: una data e un orario.
    • RegEX: un’espressione regolare per lavorare con le stringhe.
    • (…)

Parecchi, eh? Tranquilli non c'è bisogno che li conosciate tutti a memoria, vedremo durante questa guida i principali che vengono utilizzati più di frequente.

Con l'operatore typeof possiamo verificare il tipo di dato associato a un espressione. Se facciamo alcune prove possiamo notare alcune importanti differenze con Python, ad esempio in JS non c’è distinzione tra numeri interi e float:

> typeof 3
< "number"

> typeof 3.0
< "number"

Le stringhe e i booleani invece sono i seguenti:

> typeof "3"
< "string"

> typeof "ciao"
< "string"

> typeof true
< "boolean"

Quelle che in Python chiamiamo liste vengono chiamate Array e sono considerati oggetti:

> typeof [5, 2, 1]
< "object"

Otteniamo object anche se utilizziamo typeof su null:

> typeof null
< "object"

> typeof undefined
< "undefined"

Attenzione a combinare i tipi di dato diversi tra di loro: in JavaScript possiamo ottenere dei risultati inaspettati o quantomeno controintuitivi:

> 1 + 1
< 2

> 1 + "1"
< "11"

> 1 + "1" - "1"
< 10

> 1 + "1" - "1" + "1"
< 101

Python invece avrebbe restituito un’eccezione dicendo che l'operatore + non è supportato per una somma tra interi e stringhe:

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Queste che sembrano stranezze dal punto di vista di uno sviluppatore Python, sono ovviamente dovute al fatto che si tratta di due linguaggi distinti che hanno quindi delle meccaniche differenti: in Python è anche possibile definire la funzionalità dell’operatore + per tipi di dato da noi creati tramite delle classi.


Sintassi

Operatori Booleani

In Python gli operatori booleani sono and, not e or, mentre in JavaScript sono && (end), || (or) e ! (not):

> 0 && 1
< 0

> 0 || 1
< 1

> ! 0 && 1
< 1

Valori Booleani

I valori booleani sono scritti in maiuscolo in Python e in minuscolo in JavaScript.

> 1 == 1
< true

> 1 == 0
< false

Operatori di comparazione

Per quanto riguarda gli operatori di comparazione ci sono alcune differenze sostanziali tra Python e JavaScript che vanno evidenziate: in JS esistono infatti due operatori di l’uguaglianza: == e ===.

Il primo effettua comparazioni abstract: gli operanti vengono prima convertiti allo stesso tipo e poi viene effettuata la comparazione.

> 1 == "1"
< true

Il secondo invece effettua comparazioni strict: true viene restituito solo se tipi e valori degli operandi combaciano.

> 1 === "1"
< false

> 1 === 1
< true

Lo stesso discorso vale anche per gli operatori di disuguaglianza != e !==.

Questo comportamento apparentemente contro intuitivo può essere notato anche con l’utilizzo degli altri operatori di comparazione come <, <=, > e >, >=.

> 5 > "3"
< true

> 22 < "11" 
< false

> 5 >= "4"
< true


Variabili

Mentre in Python per dichiarare le variabili dobbiamo solo specificare un nome e assegnare loro un valore, in JavaScript dobbiamo far precedere il nome della variabile da una parola chiave che identifichi la tipologia di variable che vogliamo creare.

Ci sono tre diverse parole chiave:

  • var: utilizzata per la definizione di variabili con function scope e global scope.
  • let: utilizzata per la definizione di variabili con block scope.
  • const: utilizzata per la definizione di costanti.

La parola chiave var

Le variabili dichiarate globalmente (quindi fuori da una funzione) hanno Global Scope, quindi fanno parte dell'ambito globale: se inizializziamo una variabile x a un numero (nell’esempio 1945), possiamo richiamarne il valore in tutto il codice.

Nell’esempio mandiamo in output in console il valore di x tramite console.log() sia dall’interno di una funzione che dall’esterno.

var x = 1945;

// questo codice può usare x

console.log(x);

function miaFunzione() {
  // anche il codice qui può usare x
  console.log(x);

}

Il discorso cambia quando utilizziamo var per definire una variabile all'interno di una funzione: in questo caso la variabile farà parte dell'ambito locale della funzione stessa e per questo motivo si dice che ha Function Scope. All'esterno della funzione non possiamo utilizzare il valore assegnato:

// il codice qui non può usare pi

function miaFunzione() {
  // anche il codice qui può usare x
  var pi = 3.14;
  // il codice qui può usare pi
}

// il codice qui NON può usare pi

Questo avviene perché l'ambito di una variabile dichiarata utilizzando var corrisponde al suo attuale contesto di esecuzione.

La parola chiave let

Grazie alla parola chiave let le variabili possono avere Block Scope, ovvero un ambito strettamente legato a quello che è il blocco di codice in cui stiamo andando a definire la variabile stessa. Le variabili dichiarate con let all'interno di blocchi di codice delimitati dalle parentesi graffe non possono essere usate all'esterno del blocco stesso, quindi anche se ci troviamo all'interno di una funzione e definiamo una variabile all'interno di un blocco di codice questa non può essere usata al di fuori:

// z NON può essere usata qui

{
  (...)
  let z = “orange”;
  (...)
}

// z NON può essere usata qui

Quindi utilizzando la parola chiave let possiamo mantenere un codice più ordinato ed aggirare eventuali fastidiosi problemi che si manifestano con l'uso di var! Ad esempio, se assegniamo una variabile con var e poi lo riassegniamo all’interno di una funzione, la nostra modifica al valore varrà anche all’esterno:

var x = 10;
// qua fuori a x corrisponde 10

{
  var x = 2;
  // qui dentro a x ora corrisponde 2
}

// anche qua fuori a x ora corrisponde 2!

Mentre utilizzando let la variabile avrà Block Scope: quindi se all’interno della funzione riassegniamo x con let, il valore assegnato con var non verrà coinvolto nella modifica:

var x = 10;
// qua fuori a x corrisponde 10

{
 let x = 2;
 // qui dentro a x ora corrisponde 2
}

// qua fuori a x corrisponde ancora 10

La parola chiave const

Il valore di una variabile dichiarata con const (che significa “constant”, in italiano “costante”) non può essere cambiato, quindi se assegniamo una variabile con const e poi proviamo a riassegnarla, otterremo un errore:

> const pi = 3.14;
< undefined
> pi
< 3.14
> pi = 1936.27;

Uncaught TypeError: Assignment to constant variable.


Indentazione

In Python utilizziamo l'indentazione per separare i blocchi di codice, altrimenti l’interprete non riuscirà a leggerlo e ci darà una sfilza di errori. In JavaScript invece non è obbligatoria! Viene comunque utilizzata dagli sviluppatori ed è fortemente consigliata per rendere il codice più leggibile e comprensibile e per incrementarne la mantenibilità nel lungo termine.

Molti sviluppatori JavaScript preferiscono l'indentazione a 2 spazi perché riduce la quantità di spazio orizzontale necessaria per indentare il codice rendendolo più compatto, altri preferiscono l'indentazione a 4 spazi perché rende più facile distinguere i livelli di indentazione: qualsiasi sia la vostra scelta, l’importante è riimanere coerenti, almeno all'interno di un singolo progetto. Noi utilizzeremo l’indentazione a 2.

Il fatto che in JS l'indentazione non sia obbligatoria è un vantaggio perché permette la minimizzazione del codice (in inglese minify), una tecnica di ottimizzazione che consiste nell’eliminare spazi, commenti e caratteri superflui. Si tratta di una pratica molto comune soprattutto in produzione e per applicarla esistono diversi strumenti, come siti web e plugin. Grazie alla minimizzazione possiamo ridurre la dimensione del codice e quindi velocizzare i tempi di caricamento delle nostre pagine web migliorando l'esperienza di navigazione.


Funzioni

Vediamo le differenze che ci sono tra Python e JavaScript nel definire una funzione. In Python usiamo la parola chiave def, mentre in JS usiamo function. Inoltre in Python utilizziamo i due punti, andiamo a capo e indentiamo, mentre in JavaScript usiamo le due parentesi graffe per definire il blocco di codice:

# Python

def somma(a, b):
    return a + b
// JavaScript

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

Questo non è l'unico modo in cui è possibile definire delle funzioni in JavaScript: abbiamo la possibilità di creare le Anonymous Function e le Arrow Function, che utilizzano una sintassi differente.

Funzioni Anonime

JavaScript ci permette di definire una funzione senza darle un nome ma passandole dei parametri. Le funzioni definite in questo modo vengono chiamate Anonymous Function ("funzioni anonime").

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

Possiamo anche assegnare la funzione anonima ad una variabile, che verrà poi utilizzata per richiamarla:

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

Funzioni Arrow

Il nome delle Arrow Function (”funzioni freccia”) deriva dal fatto che usiamo il simbolo => per definirle:

(a, b) => { return a + b };
(a, b) => a + b;

Anche in questo caso possiamo assegnare le funzioni a delle variabili che poi possiamo utilizzare appunto per richiamarle o utilizzarle in altri specifici contesti.

let somma = (a, b) => { return a + b };
let somma = (a, b) => a + b;


Classi

Con Python definiamo una classe chiamata Persona con un metodo chiamato profilo:

# Python

class Persona:

    def __init__(self, nome, cognome):
        self.nome = nome
        self.cognome = cognome

    def profilo(self):
        print(f"Profilo: {self.nome} {self.cognome}")


p = Persona("Marco", "Aurelio")
p.profilo()

Vediamo ora la stessa classe Persona con lo stesso metodo profilo ma scritta utilizzando JavaScript:

// JavaScript

class Persona {

  constructor(nome, cognome) {
    this.nome = nome;
    this.cognome = cognome;
  }

  profilo() {
    console.log(`Profilo: ${this.nome} ${this.cognome}`)
  }
}

p = new Persona("Marco", "Aurelio");
p.profilo()

In JS abbiamo un metodo costruttore a cui passiamo alcuni parametri che diventeranno i parametri della nostra istanza che funziona in modo analogo ad init, e si utilizza this al posto di self.

Per mostrare in console il nome e il cognome tramite il metodo profilo abbiamo utilizzato l’accento grave (in inglese “backtick”) dei cosiddetti Template Literals, che ci permettono di utilizzare la sintassi con il simbolo del dollaro e le parentesi graffe mostrare i valori associato in modo molto simile alle f-string di Python.

Inoltre in Python, per assegnare una variabile alla classe e ottenere un’istanza utilizziamo il simbolo di assegnazione =, in JavaScript dobbiamo usare anche la parola chiave new e specificare che vogliamo creare un nuovo oggetto.

Ereditarietà

Per quanto riguarda l’ereditarietà tra le classi, in Python ci basta passare il nome della classe che stiamo andando ad estendere come argomento della classe “figlia”:

class Studente(Persona):
    # resto del codice

In JavaScript dobbiamo usare anche la parola chiave extends:

class Studente extends Persona {
  // resto del codice
}


Strutture di controllo

A parte nel caso del ciclo for, le strutture di controllo in JavaScript e Python sono molto simili.

Istruzioni condizionali

Le istruzioni condizionali si scrivono in maniera molto simile nei due linguaggi. Con Python, usiamo if, else ed elif:

# Python

age = 26  # età
driving_license = True  # patente

if age >= 18 and driving_license == True:
    print('Puoi noleggiare una Ducati!')
elif age >= 18 and driving_license == False:
    print('Niente patente, niente Ducati!')
else:
    print('Per ora niente moto!')

Con JavaScript abbiamo else if al posto di elif (che in Python ne costituisce un’abbreviazione) e utilizziamo le parentesi tonde per definire la clausola di controllo che vogliamo verificare. Inoltre utilizziamo il triplo uguale === che abbiamo visto quando abbiamo parlato degli operatori di comparazione perché al doppio uguale di Python corrisponde una comparazione strict.

// JavaScript

var age = 26;
var driving_license = true;

if (age >= 18 && driving_license === true) {
  console.log('Puoi noleggiare una Ducati!');
} else if (age >= 18 && driving_license === false) {
  console.log('Niente patente, niente Ducati!');
} else {
  console.log('Per ora niente moto!');
}

Ciclo while

Anche il ciclo while è piuttosto simile in Python e in JavaScript. Scriviamone uno che incrementi un contatore per 10 iterazioni:

# Python

contatore = 0

while contatore < 10:
    print(contatore)
    contatore += 1

Con JavaScript come in Python utilizziamo la parola chiave while, ma la definizione della clausola di controllo in JS deve stare all'interno di parentesi tonde. Viene utilizzato += per incrementare il contatore, anche se in JavaScript è possibile utilizzare direttamente il nome della variabile da incrementare seguito da ++.

// JavaScript

var contatore = 0;

while (contatore < 10) {
  console.log(contatore);
  contatore += 1;
}

Ciclo for

Le differenze tra i due linguaggi invece sono più evidenti per quanto riguarda la sintassi del ciclo for: scriviamone uno che mandi in output i numeri da 0 a 10.

In Python ci basta utilizzare la funzione range per la variabile che rappresenta l’elemento corrente della sequenza di numeri. Abbiamo chiamato l’elemento “numero”, ma avremmo potuto dargli qualsiasi altro nome.

# Python

for numero in range(11):
    print(numero)

In JavaScript abbiamo sempre la parola chiave for, però il loop è composto da tre parti: prima assegniamo la variabile i, poi per utilizzarla come contatore all’interno delle parentesi tonde le assegniamo un valore iniziale, imponiamo che sia minore o uguale a 10 e la incrementiamo usando ++ ad ogni iterazione.

// JavaScript

var i;

for (i = 0; i <= 10; i++) {
  console.log(i);
}

Sono presenti anche delle altre tipologie di cicli in JavaScript, che però vanno oltre lo scopo di questa guida.


Gestione degli errori

Anche nel caso della gestione degli errori, i due linguaggi sono molto simili. In Python utilizziamo le parole chiave try, except e finally:

# Python

try:
    # blocco di codice da provare
except Exception:
    # blocco di codice che gestisce gli errori
finally:
    # blocco di codice che verrà comunque eseguito

In JavaScript abbiamo catch(err) al posto di except e come di consueto dobbiamo inserire i blocchi all’interno di parentesi graffe. Inoltre, mentre in Python il blocco finally è opzionale, in JS è obbligatorio.

// JavaScript

try {
  // blocco di codice da provare
}
catch(err) {
  // blocco di codice che gestisce gli errori
}
finally {
  // blocco di codice che verrà comunque eseguito
}

Fine Prima Parte!

Nella seconda parte di questa guida metteremo in pratica quello che abbiamo imparato con vari esempi di codice. Prenderemo confidenza con i casi d’uso più comuni d'utilizzo in ambito web: impareremo a manipolare il contenuto e il comportamento delle pagine HTML, a impedire il ricaricamento delle pagine, fare richieste asincrone ad un’API e tanto altro ancora!


Vuoi imparare Python come un/a professionista? Dai uno sguardo ai nostri