Glossary #
Fondamenti di Programmazione e Strutture Dati
Logica & Linguaggi
Algoritmo (Algorithm)
Un algoritmo è una serie di istruzioni per eseguire una funzione.
In altre parole, un algoritmo è un mezzo per descrivere un modo per risolvere un problema in modo che possa essere risolto ripetutamente, da esseri umani o macchine. Gli informatici confrontano l'efficienza degli algoritmi attraverso il concetto di "complessità algoritmica (Algorithmic Complexity)" o notazione "Big O"
Programmazione informatica (Computer Programming)
La programmazione informatica è il processo di composizione e organizzazione di un insieme di istruzioni. Queste istruzioni indicano a un programma informatico/software cosa fare in un linguaggio comprensibile al computer. Queste istruzioni sono disponibili in molti linguaggi diversi, come C++, Java, JavaScript, HTML, Python, Ruby e Rust.
Utilizzando un linguaggio appropriato, è possibile programmare/creare qualsiasi tipo di software. Ad esempio, un programma che aiuta gli scienziati con calcoli complessi, un database che memorizza enormi quantità di dati, un sito web che consente di scaricare musica o un software di animazione che consente di creare filmati animati.
Flusso di controllo (Control flow)
Il flusso di controllo è l'ordine in cui il computer esegue le istruzioni in uno script.
Il codice viene eseguito in ordine dalla prima all'ultima riga del file, a meno che il computer non si imbatta in strutture (estremamente frequenti) che modificano il flusso di controllo, come istruzioni condizionali e cicli.
Funzione (Function)
Una funzione è un frammento di codice che può essere richiamato da altro codice o da se stessa, oppure da una variabile che fa riferimento alla funzione. Quando una funzione viene richiamata, gli argomenti vengono passati alla funzione come input e la funzione può facoltativamente restituire un valore. Una funzione in JavaScript è anche un oggetto.
Un nome di funzione è un identificatore incluso come parte di una dichiarazione o espressione di funzione. L' ambito del nome di funzione dipende dal fatto che il nome di funzione sia una dichiarazione o un'espressione.
Different types of functions
Una funzione anonima (anonymous function) è una funzione senza un nome. Solo le espressioni di funzione possono essere anonime, mentre le dichiarazioni di funzione devono avere un nome:
// Anonymous function created as a function expression
(function) () {});
// Anonymous function created as an arrow function
() => {};
Una funzione denominata (named function) è una funzione con un nome di funzione:
// Function declaration
function foo() {};
// Named function expression
(function bar() {})
// Arrow function
const baz = () => {};
Una funzione interna (inner function) è una funzione all'interno di un'altra funzione (squarein questo caso). Una funzione esterna (outer function) è una funzione che contiene una funzione (addSquaresin questo caso):
function foo(a, b) {
function square(x) {
return x * x;
}
return square(a) + square(b)
}
// Arrow function
const addSquares2 = (a, b) => {
const square = (x) => x * x;
return square (a) + square(b);
};
Una funzione ricorsiva (recursive function) è una funzione che richiama se stessa
function loop(x) {
if (x >= 10) return;
loop2(x + 1);
}
// Arrow function
function loop2 = (x) => {
if (x >= 10) return;
loop2(x + 1);
};
Un'espressione di funzione immediatamente richiamata (Immediately Invoked Function Expression - IIFE) è una funzione che viene chiamata subito dopo essere stata caricata nel compilatore del browser. Il modo per identificare un'IIFE è individuare le parentesi aggiuntive sinistra e destra alla fine della definizione della funzione.
Le espressioni di funzione, denominate o anonime, possono essere chiamate immediatamente.
(function foo() {
console.log("Hello Foo");
})();
(() => console.log("Hello Foo"))();
Le funzioni dichiarate non possono essere chiamate immediatamente in questo modo, perché le IIFE devono essere espressioni di funzione.
function foo() {
console.log("Hello Foo");
}();
IIFE
Una IIFE (Immediately Invoked Function Expression) è un'espressione idiomatica in cui una funzione JavaScript viene eseguita non appena definita. È anche nota come funzione anonima auto-eseguibile.
// standard IIFE
(function () {
// statements
})();
// arrow function variant
(() => {
// statements
})();
// async IIFE
(async () => {
// statements
})();
- Un'espressione di funzione. Solitamente deve essere racchiusa tra parentesi per essere analizzata correttamente.
- Chiamata immediata dell'espressione della funzione. È possibile fornire argomenti, sebbene le funzioni IIFE senza argomenti siano più comuni.
Gli IIFE sono un pattern comune utilizzato per eseguire un numero arbitrario di istruzioni nel proprio ambito (ed eventualmente restituire un valore), in una posizione che richiede una singola espressione. Sono simili, ma molto più potenti, dell'operatore virgola , che può eseguire solo più espressioni e, pertanto, non fornisce un modo per utilizzare variabili locali o istruzioni di controllo del flusso.
I casi d'uso degli IIFE includono:- Evitare di contaminare lo spazio dei nomi globale creando un nuovo ambito.
- Creazione di un nuovo contesto asincrono da utilizzare await in un contesto non asincrono.
- Calcolo di valori con logica complessa, ad esempio utilizzando più istruzioni come un'unica espressione.
Metodo (Method)
Un metodo è una funzione che rappresenta una proprietà di un oggetto. Esistono due tipi di metodi: metodi di istanza, che sono attività predefinite eseguite da un'istanza di oggetto, e metodi statici, che sono attività chiamate direttamente da un costruttore di oggetto.
Nota
In JavaScript le funzioni stesse sono oggetti, quindi, in quel contesto, un metodo è in realtà un riferimento a un oggetto di una funzione.
Argomento (Argument)
Gli argomenti sono valori (primitivi o oggetti) passati come input a una funzione. Non confondere gli argomenti con i parametri, che sono i nomi utilizzati nella definizione della funzione per fare riferimento agli argomenti.
const argument1 = "Web";
const argument2 = "Development";
example(argument1, argument2); // passing two arguments
// This function takes two values
function example(parameter1, parameter2) {
console.log(parameter1); // Output = "Web"
console.log(parameter2); // Output = "Development"
}
L'ordine degli argomenti all'interno della chiamata di funzione dovrebbe essere lo stesso dell'ordine dei parametri nella definizione della funzione.
const argument1 = "foo";
const argument2 = [1, 2, 3];
example(argument1, argument2); // passing two arguments
// This function takes a single value, so the second argument passed is ignored
function example(parameter) {
console.log(parameter); // Output = "foo"
}
Parametro (Parameter)
I parametri sono variabili denominate dichiarate come parte di una funzione. Vengono utilizzate per fare riferimento agli argomenti passati alla funzione.
const argument1 = "Web";
const argument2 = "Development";
example(argument1, argument2); // passing two arguments
// This function takes two values
function example(parameter1, parameter2) {
console.log(parameter1); // Output = "Web"
console.log(parameter2); // Output = "Development"
}
Firma di funzione (Function signature)
Una firma di funzione (o firma di tipo o firma di metodo) definisce l'input e l'output di funzioni o metodi.
Una firma può includere:- Parametri e loro tipi
- Un valore di ritorno e un tipo
- Eccezioni che potrebbero essere generate o trasmesse indietro
- Informazioni sulla disponibilità del metodo in un programma orientato agli oggetti (come le parole chiave public, static, o prototype).
Firme in JavaScript
JavaScript è un linguaggio debolmente tipizzato o dinamico. Ciò significa che non è necessario dichiarare il tipo di una variabile in anticipo. Il tipo verrà determinato automaticamente durante l'elaborazione del programma. Una firma in JavaScript può comunque fornire alcune informazioni sul metodo:
MyObject.prototype.myFunction(value);
Firme in Java
In Java, le firme vengono utilizzate per identificare metodi e classi a livello del codice della macchina virtuale. È necessario dichiarare i tipi di variabili nel codice per poter eseguire il codice Java. Java è strettamente tipizzato e verifica la correttezza di tutti i parametri in fase di compilazione.
public static void main(String[] args);
- La parola chiave public è un modificatore di accesso e indica che questo metodo può essere chiamato da qualsiasi oggetto.
- La parola chiave static indica che questo metodo è un metodo di classe e non un metodo di istanza.
- La parola chiave void indica che questo metodo non ha alcun valore di ritorno.
- Il nome del metodo è main.
- Il metodo accetta un parametro di tipo String Array. Si chiama args.
API
Un'API (Application Programming Interface) è un insieme di funzionalità e regole presenti all'interno di un programma software (l'applicazione) che consentono l'interazione con esso tramite software, a differenza di un'interfaccia utente umana. L' API può essere vista come un semplice contratto (l'interfaccia) tra l'applicazione che la offre e altri elementi, come software o hardware di terze parti.
Nello sviluppo Web, un'API è generalmente un insieme di funzionalità di codice (ad esempio metodi, proprietà, eventi e URL) che uno sviluppatore può utilizzare nelle proprie app per interagire con i componenti del browser Web di un utente, altri software/hardware sul computer dell'utente o siti Web e servizi di terze parti.
Tipo (Type)
Il tipo è una caratteristica di un valore che influenza il tipo di dati che può memorizzare e la struttura a cui i dati aderiranno. Ad esempio, un tipo di dato booleano (Boolean) può contenere solo un valore TRUE o FALSE. Mentre una stringa (String) può contenere una stringa o una sequenza di caratteri, un numero (Number) può contenere valori numerici di qualsiasi tipo e così via.
Il tipo di dati di un valore influenza anche le operazioni valide su quel valore. Ad esempio, un valore di tipo numero può essere moltiplicato per un altro numero, ma non per una stringa, anche se questa contiene solo un numero, come la stringa "2".
Se non si è sicuri del tipo di un valore, è possibile utilizzare l'operatore typeof.
Coercizione di tipo (Type coercion)
La coercizione di tipo è la conversione automatica o implicita di valori da un tipo di dati a un altro (ad esempio, stringhe in numeri). La conversione di tipo è simile alla coercizione di tipo perché entrambe convertono i valori da un tipo di dati a un altro, con una differenza fondamentale: la coercizione di tipo è implicita, mentre la conversione di tipo può essere implicita o esplicita.
const value1 = "5";
const value2 = 9;
let sum = value1 + value2;
console.log(sum);
Nell'esempio precedente, JavaScript ha convertito il numero 9 in una stringa e poi ha concatenato i due valori, ottenendo una stringa "59". JavaScript poteva scegliere tra una stringa o un numero e ha deciso di utilizzare una stringa.
Il compilatore avrebbe potuto convertire il 5 in un numero e restituire la somma di 14, ma non l'ha fatto. Per restituire questo risultato, avresti dovuto convertire esplicitamente il 5 in un numero utilizzando il metodo Number():
sum = Number(value1) + value2;
Conversione di tipo (Type conversion)
La conversione di tipo (o typecasting) significa il trasferimento di dati da un tipo di dati a un altro. La conversione implicita avviene quando il compilatore (per i linguaggi compilati) o il runtime (per i linguaggi di scripting come JavaScript ) converte automaticamente i tipi di dati. Il codice sorgente può anche richiedere esplicitamente che venga eseguita una conversione.
Ad esempio, data l'espressione "foo" + 1, il numero 1 viene convertito implicitamente in una stringa e l'espressione restituisce "foo1". Data l'istruzione Number("0x11"), la stringa "0x11" viene convertita esplicitamente in numero.
Tipizzazione statica (Static typing)
Un linguaggio staticamente tipizzato è un linguaggio (come Java, C o C++) in cui i tipi delle variabili sono noti in fase di compilazione. Nella maggior parte di questi linguaggi, i tipi devono essere espressamente indicati dal programmatore; in altri casi (come OCaml), l'inferenza di tipo consente al programmatore di non indicare i tipi delle variabili.
Tipizzazione dinamica (Dynamic typing)
I linguaggi a tipizzazione dinamica sono quelli (come JavaScript ) in cui l'interprete assegna un tipo alle variabili in fase di esecuzione in base al valore della variabile in quel momento.
Sintassi (Syntax)
La sintassi specifica la combinazione e la sequenza di caratteri richieste per costituire un codice correttamente strutturato. La sintassi generalmente include la grammatica e le regole che si applicano alla sua scrittura, come i requisiti di indentazione in Python.
La sintassi varia da linguaggio a linguaggio (ad esempio, la sintassi è diversa in HTML e JavaScript). Sebbene i linguaggi possano condividere poche somiglianze in termini di sintassi, ad esempio la regola "operando operatore operando" in JavaScript e Python, ciò non significa che i due linguaggi condividano somiglianze sintattiche.
La sintassi si applica sia ai linguaggi di programmazione (comandi al computer) sia ai linguaggi di markup (informazioni sulla struttura del documento).
La sintassi regola solo l'ordinamento e la struttura; le istruzioni devono anche essere significative, e questo è compito della semantica.
Il codice deve avere una sintassi corretta per poter essere compilato correttamente, altrimenti si verifica un errore di sintassi. Anche piccoli errori, come una parentesi mancante, possono impedire la corretta compilazione del codice sorgente.
Si dice che i framework abbiano una sintassi "pulita" se producono risultati semplici, leggibili e concisi. Se una base di codice utilizza "molta sintassi", richiede più caratteri per ottenere la stessa funzionalità.
Errore di sintassi (Syntax error)
Un'eccezione viene causata dall'uso errato di una sintassi predefinita. Gli errori di sintassi vengono rilevati durante la compilazione o l'analisi del codice sorgente.
Ad esempio, se si omette una parentesi graffa di chiusura ( }) quando si definisce una funzione JavaScript , si genera un errore di sintassi. Gli strumenti di sviluppo del browser visualizzano gli errori di sintassi JavaScript e CSS nella console.
Dichiarazione (Statement)
In un linguaggio di programmazione, un'istruzione è una riga di codice che comanda un'attività. Ogni programma è costituito da una sequenza di istruzioni. (Esempio: Assegnare un valore a una variabile)
Costante (Constant)
Una costante è un dato il cui valore non cambia durante l'esecuzione di un programma, a differenza delle variabili che possono essere modificate. È una porzione di memoria con un valore fisso, che può essere un numero, un carattere o una stringa, e spesso viene utilizzata per valori matematici come pi greco o per rappresentare impostazioni che non devono essere cambiate.
Distinzione dalle variabili: La differenza principale è che le costanti hanno un valore fisso e immutabile, mentre le variabili possono cambiare valore durante l'esecuzione del programma.
Variabile (Variable)
Una variabile è un'area di memoria che contiene dati modificabili, identificata da un nome (identificatore). Può essere pensata come una "scatola" etichettata che conserva valori, come numeri, testo o valori logici, che possono cambiare durante l'esecuzione di un programma.
Parola chiave (Keyword)
Una parola chiave è una parola o una frase che descrive un contenuto. Le parole chiave online vengono utilizzate come query per i motori di ricerca o come parole che identificano il contenuto sui siti web.
Quando si utilizza un motore di ricerca, si utilizzano parole chiave per specificare ciò che si sta cercando e il motore di ricerca restituisce pagine web pertinenti. Per risultati più accurati, si consiglia di provare parole chiave più specifiche, come "Blue Mustang GTO" anziché "Mustang". Le pagine web utilizzano anche parole chiave in un meta tag (nella <head> sezione) per descrivere il contenuto della pagina, in modo che i motori di ricerca possano identificarle e organizzarle meglio.
Letterale (Literal)
Il letterale è un valore scritto direttamente nel codice sorgente (es. 10, "ciao", 3.14). Viene utilizzato per rappresentare un valore specifico e statico nel codice.
Esempi di letterali:
// Array literals
const coffees = ["French Roast", "Kona"];
// Boolean literals
Può assumere solo TRUE o FALSE (Risultato condizione if)
// Object literals
let utente = {
nome: "John",
eta: 30
};
// RegExp literals
const re = /ab+c/;
// String literals
'foo' or "bar"
// Numeric literals
// Integer
10
-25
0
// Decimal (Floating-point literals)
3.1415926
.123456789
3.1E+12
.1e-23
// Complex
5 + 2j
7 - 3j
Simbolo (Symbol)
Un simbolo è un tipo di dato che rappresenta identificatori univoci e non falsificabili. A volte vengono chiamati atomi.
Poiché un simbolo è univoco e non falsificabile, è possibile leggere il valore di una proprietà associata a un simbolo solo se si dispone di un riferimento all'identificatore originale.
In JavaScript, symbol è uno dei tipi primitivi e può essere creato utilizzando il metodo factory Symbol() che restituisce ogni volta un simbolo diverso. Possono essere utilizzati come chiavi per oggetti che non possono mai entrare in collisione accidentale con altre proprietà.
Identificatore (Identifier)
Un identificatore è una sequenza di caratteri nel codice che identifica una variabile, una funzione o una proprietà. Nella maggior parte dei linguaggi, gli identificatori sono sensibili alle maiuscole e alle minuscole e non sono racchiusi tra virgolette.
In JavaScript, gli identificatori possono contenere lettere Unicode $ , , _e cifre (0-9), ma non possono iniziare con una cifra. Un identificatore differisce da una stringa in quanto una stringa è costituita da dati, mentre un identificatore è parte del codice. In JavaScript, non è possibile convertire gli identificatori in stringhe, ma a volte è possibile analizzare le stringhe in identificatori.
Interpolazione (Interpolation)
L'interpolazione è un metodo per stimare nuovi punti dati in base a un insieme di punti dati noti.
Compilazione (Compile)
La compilazione è il processo di trasformazione di un programma per computer scritto in un dato linguaggio in un insieme di istruzioni in un altro formato o linguaggio. Un compilatore è un programma per computer che esegue tale operazione.
In genere, un compilatore trasforma il codice scritto in un linguaggio di livello superiore come C++, Rust o Java in codice eseguibile (runnable), il cosiddetto codice binario o codice macchina.
La maggior parte dei compilatori esegue la compilazione anticipata (AOT, ahead-of-time) o la compilazione just-in-time (JIT) .
Tempo di compilazione (Compile time)
Il tempo di compilazione è la fase del ciclo di vita della programmazione durante la quale il codice sorgente di un programma viene tradotto in codice eseguibile da un compilatore. Questa fase avviene prima che il programma venga eseguito e include attività come il controllo della sintassi, la verifica dei tipi e l'ottimizzazione del codice. La durata di questa fase dipende da diversi fattori, come la complessità del codice, la potenza del computer e la velocità del compilatore.
Compilazione Just-In-Time (JIT)
JIT (Just-In-Time Compilation) è un processo di compilazione in cui il codice viene tradotto da una rappresentazione intermedia o da un linguaggio di livello superiore (ad esempio, JavaScript o Java bytecode) in codice macchina durante l'esecuzione, anziché prima dell'esecuzione. Questo approccio combina i vantaggi dell'interpretazione e della compilazione anticipata (AOT).
I compilatori JIT in genere analizzano continuamente il codice durante la sua esecuzione, identificando le parti di codice che vengono eseguite frequentemente (punti critici). Se i miglioramenti della velocità superano l'overhead di compilazione, i compilatori JIT compileranno tali parti in codice macchina. Il codice compilato viene quindi eseguito direttamente dal processore, il che può comportare significativi miglioramenti delle prestazioni.
Interprete (Interpeter)
Un interprete è un programma che traduce ed esegue codice sorgente riga per riga, senza creare un file eseguibile separato come fa un compilatore. Questo processo avviene "al volo" (runtime) e consente l'esecuzione immediata delle istruzioni, ma può risultare più lento rispetto al codice compilato, poiché la traduzione avviene ogni volta che il programma viene eseguito.
Astrazione (Abstraction)
L'astrazione nella programmazione informatica è un modo per ridurre la complessità e consentire una progettazione e un'implementazione efficienti in sistemi software complessi. Nasconde la complessità tecnica dei sistemi dietro API più semplici.
Vantaggi dell'astrazione dei dati- Aiuta l'utente a evitare di scrivere codice di basso livello.
- Evita la duplicazione del codice e aumenta la riutilizzabilità.
- Può modificare l'implementazione interna di una classe in modo indipendente senza influire sull'utente.
- Contribuisce ad aumentare la sicurezza di un'applicazione o di un programma poiché all'utente vengono forniti solo i dettagli importanti.
Esempio:
class ImplementAbstraction {
// method to set values of internal members
set(x, y) {
this.a = x;
this.b = y;
}
display() {
console.log('a = ${this.a}')
console.log('b = ${this.b}')
}
}
const obj = new ImplementAbstraction();
obj.set(10,20);
obj.display();
// a = 10
// b = 20
Incapsulamento (Encapsulation)
L'incapsulamento è un concetto fondamentale in informatica che si riferisce a due aspetti: nella programmazione orientata agli oggetti, consiste nel raggruppare dati (attributi) e metodi (funzioni) in un'unica unità (la classe) e nel limitare l'accesso esterno a questi dati.
"Protezione dei dati" Limita l'accesso diretto ai dati (solitamente rendendoli privati) e impone l'uso di metodi pubblici (getter e setter) per accedervi o modificarli. Questo impedisce modifiche non autorizzate e garantisce l'integrità dei dati.
"Black box" Permette di trattare gli oggetti come "scatole nere", dove si interagisce solo attraverso l'interfaccia pubblica (i metodi), senza doversi preoccupare dei dettagli interni di implementazione.
Vantaggi: Migliora la modularità, la manutenibilità e la robustezza del codice. Le modifiche all'implementazione interna non influiscono sulle altre parti del sistema.
Eredità (Inheritance)
L'ereditarietà è una caratteristica fondamentale della programmazione orientata agli oggetti. L'astrazione dei dati può essere estesa a diversi livelli, ovvero le classi possono avere superclassi e sottoclassi.
Come sviluppatore di app, puoi scegliere quali attributi e metodi della superclasse mantenere e aggiungerne di tuoi, rendendo la definizione della classe molto flessibile. Alcuni linguaggi consentono a una classe di ereditare da più di un genitore (ereditarietà multipla).
Polimorfismo (Polymorphism)
Il polimorfismo in informatica è la capacità di un'espressione di assumere forme diverse, tipicamente nella programmazione orientata agli oggetti, dove consente a un oggetto di essere trattato come se fosse un tipo diverso, solitamente una sua superclasse comune. Ciò permette di scrivere codice più flessibile e riutilizzabile, poiché si possono chiamare metodi su oggetti diversi e il sistema saprà eseguire l'implementazione corretta per il tipo specifico dell'oggetto.
Immagina di avere una superclasse FiguraGeometrica con un metodo disegna().
- Le sottoclassi come Cerchio, Rettangolo e Linea erediteranno questo metodo.
- Ogni sottoclasse implementerà il proprio metodo disegna() in modo specifico (ad esempio, Cerchio disegnerà un cerchio, Rettangolo un rettangolo).
- Utilizzando il polimorfismo, puoi avere una collezione di FiguraGeometrica e chiamare il metodo disegna() su ciascun elemento. Il sistema eseguirà automaticamente il metodo corretto per ogni oggetto, senza che tu debba preoccuparti di che tipo di figura sia.
Overloading/Overriding
Esempi su JAVAL'overloading (o sovraccarico) permette di definire più metodi con lo stesso nome ma con firme diverse (numero o tipo di parametri) nella stessa classe, mentre l'overriding (o sovrascrittura) consente a una sottoclasse di ridefinire un metodo già esistente nella sua classe padre, mantenendo la stessa firma. L'overloading è un meccanismo di polimorfismo che viene risolto a tempo di compilazione, mentre l'overriding permette di scegliere l'implementazione corretta a tempo di esecuzione.
Esempio OverloadingSi possono definire più versioni, dello stesso metodo, variando il numero e il tipo dei parametri, e/o la visibilità. L’overloading può essere fatto nella stessa classe o anche nelle classi derivate.
class A {
public void hello() {
}
}
public class B extends A {
public void hello(int i) {
}
public void hello(String g) {
}
public void hello(int i, String h, int k) {
}
}
Se si tenta di modificare solo il tipo di ritorno di un metodo, ossia abbiamo due metodi identici tranne per il tipo di ritorno, otteniamo un errore di compilazione. Java li considera come se fossero due metodi uguali. Stessa cosa per la visibilità.
class A {
public void hello() {
}
}
public class B extends A {
public int hello(int i) { // errore: metodo duplicato
return 1;
}
public String hello(int i) { // errore: metodo duplicato
return "";
}
}
Una classe derivata può avere un metodo identico ad un metodo già presente nella classe base. Qesta operazione di riscrittura è nota come ovverride.
class A {
public void hello() {
System.out.println("metodo del padre");
}
public void prova() {
System.out.println("prova");
}
}
public class B extends A {
public void hello() {
System.out.println("metodo del figlio");
}
public static void main (String[] args) {
B tmp = new B();
tmp.hello(); //stampa "metodo del figlio", perchè stato fatto l'override del metodo
tmp.prova(); // stampa "prova", questo metodo appartiene al padre
}
}
Programmazione orientata agli oggetti (OOP - Object-Oriented Programming)
OOP (Programmazione Orientata agli Oggetti) è un paradigma di programmazione che modella i problemi del mondo reale tramite "oggetti". Questi oggetti sono istanze di "classi" e possiedono sia attributi (dati) che metodi (funzioni) che definiscono il loro comportamento. I principi chiave dell'OOP sono incapsulamento, ereditarietà e polimorfismo, che portano a vantaggi come riusabilità del codice, modularità e maggiore manutenibilità.
Classe (Class)
Nella programmazione orientata agli oggetti, una classe definisce le caratteristiche di un oggetto. La classe è una definizione modello delle proprietà e dei metodi di un oggetto, il "progetto" da cui vengono ricavate altre istanze più specifiche dell'oggetto.
Istanza (Instance)
Un'istanza è un oggetto specifico creato a partire da un modello generale, o classe. Una classe è un "modello" che definisce le caratteristiche e il comportamento di un tipo di oggetto, mentre ogni istanza è una realizzazione concreta di quel modello, come ad esempio "cane1" e "cane2" sono istanze della classe "Cane".
Costruttore (Constructor)
Un costruttore è un metodo speciale chiamato quando si crea un oggetto (un'istanza) di una classe, con lo scopo di inizializzare l'oggetto e impostare i suoi valori iniziali. I costruttori sono fondamentali nella programmazione orientata agli oggetti e servono a preparare l'oggetto per l'uso, assicurando che sia in uno stato valido fin dall'inizio.
Prototipo (Prototype)
Un prototipo è un modello iniziale e approssimato che serve a visualizzare e testare come un'applicazione o un prodotto apparirà e funzionerà prima dello sviluppo completo. È uno strumento prezioso per raccogliere feedback, validare il design e il concetto, identificare potenziali problemi e ridurre i rischi e i costi associati a modifiche in una fase successiva.
Programmazione basata su prototipi (Prototype-based programming)
La programmazione basata sui prototipi è uno stile di programmazione orientata agli oggetti in cui le classi non sono definite esplicitamente, ma piuttosto derivate aggiungendo proprietà e metodi a un'istanza di un'altra classe o, meno frequentemente, aggiungendoli a un oggetto vuoto. Questo tipo di stile consente di creare un oggetto senza prima definirne la classe.
Garbage collection
Garbage collection è un termine utilizzato nella programmazione informatica per descrivere il processo di ricerca ed eliminazione di oggetti che non sono più referenziati da altri oggetti.
In altre parole, la garbage collection è il processo di rimozione di tutti gli oggetti che non vengono utilizzati da altri oggetti. Spesso abbreviata con "GC", la garbage collection è un componente fondamentale del sistema di gestione della memoria utilizzato da JavaScript.
Vantaggi- Meno bug: Evita gli errori legati alla gestione manuale della memoria, come le memory leak e l'accesso a memoria non valida.
- Migliore performance: Le performance possono essere ottimizzate, ad esempio, separando gli oggetti per dimensione o raggruppando quelli di breve durata in "generazioni" che vengono raccolte più frequentemente.
Flag bit a bit (Bitwise flags)
I bitwise flags sono un modo per usare i bit di un singolo numero intero per memorizzare più stati booleani (sì/no) contemporaneamente, invece di usare variabili booleane separate. Un operatore bit a bit manipola i singoli bit di un numero. Un esempio pratico è rappresentare più permessi in un unico intero: potresti avere il bit 1 per il permesso di lettura e il bit 3 per il permesso di scrittura.
Esempio praticoImmagina di voler rappresentare permessi utente in un programma:
- Permesso di lettura: bit 0 (20 = 1)
- Permesso di scrittura: bit 1 (21 = 2)
- Permesso di scrittura: bit 2 (22 = 4)
Se un utente ha solo il permesso di lettura, la sua variabile permessi avrà il valore 1. Se ha lettura e scrittura, il valore sarà (1 + 2 = 3).
Condizione (Condition)
Una condizione è un insieme di regole che possono interrompere la normale esecuzione del codice o modificarla, a seconda che la condizione venga completata o meno.
Un'istruzione o un insieme di istruzioni viene eseguito se una condizione specifica è soddisfatta. In caso contrario, viene eseguita un'altra istruzione. È anche possibile ripetere l'esecuzione di un'istruzione, o di un insieme di istruzioni, mentre una condizione non è ancora soddisfatta.
Loop
Un loop è una sequenza di istruzioni che viene ripetuta finché non viene soddisfatta una determinata condizione. Un esempio potrebbe essere il processo di acquisizione di un dato e modificarlo, per poi assicurarsi che una determinata condizione venga verificata, ad esempio se un contatore ha raggiunto un numero prestabilito.
I cicli sono un modo per eseguire un'istruzione per un numero variabile di volte. Lo stesso effetto può essere ottenuto con la ricorsione , soprattutto nei linguaggi in cui tutti i dati sono immutabili , rendendo impossibile aggiornare una variabile contatore.
Ricorsione (Recursion)
La ricorsione, ovvero l'atto di una funzione che richiama se stessa, viene utilizzata per risolvere problemi che contengono sottoproblemi più piccoli. Una funzione ricorsiva può ricevere due input: un caso base (che termina la ricorsione) o un caso ricorsivo (che riprende la ricorsione).
Dati & Strutture
Struttura dei dati (Data structure)
La struttura dei dati è un modo particolare di organizzare i dati in modo che possano essere utilizzati in modo efficiente.
Vettore (Array)
Un array è una raccolta ordinata di dati (primitivi o oggetti, a seconda del linguaggio). Gli array vengono utilizzati per memorizzare più valori sotto un unico nome di variabile. Una variabile normale, invece, può memorizzare un solo valore.
Ogni elemento di un array è associato a un numero, chiamato indice numerico, che consente di accedervi. In JavaScript, gli array partono dall'indice zero e possono essere manipolati con vari metodi.
Gli array in JavaScript hanno questo aspetto:
// Arrays in JavaScript can hold different types of data
const myArray = [1, 2, 3];
const myArray = ["Barbie", "Ken", "Midge"];
// Array indexes starts at 0.
console.log(myArray[0]); // output: 1
console.log(myArray[2]); // output: "Midge"