17 marzo 2025
Variabili e Tipi di Dati
var, let, const
Una delle caratteristiche principali introdotte con ES6 è l’aggiunta di let
e const
per la dichiarazione delle variabili. Prima di ES6, var
era il metodo principale per dichiarare variabili, ma presentava diversi problemi.
Var
L’ambito di una variabile definisce dove può essere accessibile. Le variabili dichiarate con var
hanno un ambito globale o di funzione. Se dichiarate a livello globale, possono essere accessibili ovunque nella finestra.
Esempio:
var greeter = "hey hi";
var greeter = "say Hello instead"; // Re-declaration is allowed
Il problema con var
è che la ri-dichiarazione di una variabile può portare a risultati inaspettati nel codice.
Let
let
è stato introdotto per migliorare var
. Ha un ambito di blocco, il che significa che può essere accessibile solo all’interno del blocco {}
in cui è stato dichiarato. Sebbene le variabili dichiarate con let
possano essere aggiornate, non possono essere ri-dichiarate.
Esempio:
let message = "Hello";
message = "Hi"; // Allowed
let message = "Hey"; // Syntax Error
Un’altra differenza fondamentale è il hoisting. Quando si tenta di accedere a una variabile sollevata prima della sua dichiarazione:
var
ritornaundefined
let
genera unReferenceError
Const
Le variabili dichiarate con const
sono costanti, il che significa che i loro valori non possono essere aggiornati né ri-dichiarati. Come let
, const
ha un ambito di blocco.
Esempio:
const PI = 3.1416;
PI = 3.14; // TypeError: Assignment to constant variable
Tuttavia, gli oggetti e gli array dichiarati con const
possono essere modificati:
const person = { name: "John" };
person.name = "Jane"; // Allowed
Tipi Primitivi
I tipi primitivi definiscono valori immutabili e sono rappresentati al livello più basso di JavaScript. Questi tipi includono:
Tipo | typeof return value | Object Wrapper |
---|---|---|
Null | ”object” | N/A |
Undefined | ”undefined” | N/A |
Boolean | ”boolean” | Boolean |
Number | ”number” | Number |
BigInt | ”bigint” | BigInt |
String | ”string” | String |
Symbol | ”symbol” | Symbol |
Null
Rappresenta un’assenza intenzionale di un valore.
let x = null;
Undefined
Rappresenta una variabile non inizializzata.
let y;
console.log(y); // undefined
Boolean
Rappresenta i valori true o false, comunemente utilizzati nelle condizioni.
let isActive = true;
Number
JavaScript utilizza numeri in virgola mobile a doppia precisione a 64 bit.
let num = 42;
let big = Number.MAX_SAFE_INTEGER;
Valori speciali:
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(0 / 0); // NaN
BigInt
Per gestire interi oltre Number.MAX_SAFE_INTEGER
.
let bigInt = 123456789012345678901234567890n;
String
Dati testuali, immutabili.
let greeting = "Hello, world!";
Symbol
Un identificatore unico, spesso utilizzato per le chiavi delle proprietà degli oggetti.
let sym = Symbol("unique");
Tipi di Riferimento
A differenza dei tipi primitivi, i tipi di riferimento memorizzano indirizzi di memoria invece dei valori.
Oggetti
Gli oggetti memorizzano coppie chiave-valore.
let person = {
name: "Alice",
age: 25,
};
Array
Collezioni ordinate di valori.
let numbers = [1, 2, 3, 4, 5];
Funzioni
Un oggetto chiamabile.
function greet() {
console.log("Hello");
}
Map & Set
Map: Memorizza coppie chiave-valore.
Set: Memorizza valori unici.
Esempio:
let myMap = new Map();
myMap.set("key", "value");
let mySet = new Set([1, 2, 3]);
Questi tipi di riferimento permettono a JavaScript di gestire i dati complessi in modo efficiente.
Template Literals
I template literals, introdotti in ES6, consentono una più semplice interpolazione di stringhe e stringhe su più righe. Questi sono racchiusi tra backtick (`) e supportano espressioni incorporate.
Interpolazione di Stringhe di Base
Puoi incorporare espressioni direttamente all’interno dei template literals utilizzando la sintassi ${}
:
let name = "Alice";
let greeting = `Hello, ${name}!`; // String interpolation
console.log(greeting); // "Hello, Alice!"
Stringhe su Più Righe
I template literals rendono anche più facile lavorare con stringhe su più righe:
let multilineString = `This is a
multi-line
string!`;
console.log(multilineString);
// Output:
// This is a
// multi-line
// string!
Espressioni e Calcoli
I template literals permettono espressioni più complesse all’interno di ${}
:
let a = 10;
let b = 20;
let result = `The sum of ${a} and ${b} is ${a + b}.`;
console.log(result); // "The sum of 10 and 20 is 30."
Questa funzionalità migliora la leggibilità del codice e riduce la necessità di concatenazione di stringhe.
Nomenclatura
Scegliere nomi di variabili significativi è una pratica fondamentale per scrivere codice leggibile e manutenibile. Ecco alcune migliori pratiche e linee guida per la denominazione delle variabili in JavaScript:
Nomi Descrittivi
Le variabili dovrebbero essere denominate in modo da indicare chiaramente cosa rappresentano. Ad esempio:
let firstName = "Alice"; // Clear and descriptive
let age = 30; // Describes the person's age
Convenzione CamelCase
In JavaScript, si usa comunemente il camelCase per i nomi delle variabili e delle funzioni. La prima parola inizia con una lettera minuscola, e ogni parola successiva inizia con una lettera maiuscola.
let userAge = 25;
let userFullName = "John Doe";
Costanti in Maiuscolo
Per le costanti, è pratica comune usare tutte le lettere maiuscole con gli underscore che separano le parole.
const MAX_USERS = 100;
const API_URL = "https://api.example.com";
Evitare Parole Riservate
Evita di utilizzare parole chiave riservate di JavaScript come let
, var
, if
, else
, class
, function
e altre come nomi di variabili.
Significativo, ma Conciso
Scegli nomi di variabili che siano sia significativi che concisi per garantire chiarezza senza verbosità inutile. Ad esempio, count
è migliore di counterVariable
, e isActive
è più informativo di statusFlag
.
Riferimento alla Memoria (Memory Reference)
Primitivi vs Tipi di Riferimento
In JavaScript, le variabili possono contenere valori primitivi o valori di riferimento. Questa distinzione gioca un ruolo fondamentale nel modo in cui i valori vengono memorizzati e manipolati in memoria.
Tipi Primitivi
I tipi primitivi sono memorizzati direttamente in memoria. Quando una variabile viene assegnata a un valore primitivo, il valore stesso viene memorizzato nella variabile:
let x = 10; // x stores the value 10 directly in memory
let y = x; // y now stores a copy of x's value
x = 20; // Changing x does not affect y
console.log(x); // 20
console.log(y); // 10
In questo esempio, x
e y
memorizzano valori indipendenti. Le modifiche a x
non influenzano y
.
Tipi di Riferimento
I tipi di riferimento (come oggetti, array e funzioni) sono memorizzati come riferimenti (indirizzi di memoria). Quando una variabile viene assegnata a un valore di tipo riferimento, memorizza l’indirizzo dell’oggetto in memoria, non l’oggetto stesso.
let obj1 = { name: "Alice" };
let obj2 = obj1; // obj2 now references the same object as obj1
obj1.name = "Bob"; // Changing obj1 will also affect obj2
console.log(obj1.name); // "Bob"
console.log(obj2.name); // "Bob"
Qui, sia obj1
che obj2
fanno riferimento allo stesso oggetto in memoria. Modificare l’oggetto tramite uno dei due riferimenti influenzerà entrambe le variabili perché puntano alla stessa posizione in memoria.
Passaggio per Valore vs Passaggio per Riferimento
Quando si passano variabili alle funzioni:
- I tipi primitivi vengono passati per valore: la funzione riceve una copia del valore.
- I tipi di riferimento vengono passati per riferimento: la funzione riceve un riferimento all’oggetto originale, permettendo la modifica dell’oggetto.
Esempio per i tipi primitivi:
function changeValue(num) {
num = 100;
}
let myNumber = 50;
changeValue(myNumber);
console.log(myNumber); // 50, original value is unchanged
Esempio per i tipi di riferimento:
function changeObject(obj) {
obj.name = "Charlie";
}
let myObject = { name: "Alice" };
changeObject(myObject);
console.log(myObject.name); // "Charlie", the object is modified
In sintesi, comprendere come JavaScript gestisce i riferimenti in memoria è fondamentale per gestire le variabili, specialmente quando si lavora con tipi di dati complessi come oggetti e array.