Oggetti JavaScript: Proprietà e Metodi
Impara a lavorare con gli oggetti, le proprietà, i metodi e le operazioni fondamentali
🎁 Cos’è un Oggetto in JavaScript?
Un oggetto è una collezione di proprietà, dove ogni
proprietà è una coppia chiave-valore. Gli oggetti sono fondamentali
per organizzare dati complessi e rappresentare entità del mondo reale.
💡 Oggetti nel Mondo Reale
Pensa a un oggetto come a una scheda descrittiva: una persona
ha nome, cognome, età, indirizzo. Un libro ha titolo, autore, anno, pagine.
Gli oggetti JavaScript ti permettono di raggruppare queste informazioni correlate!
- Lista ordinata
- Accesso per indice numerico
- Elementi omogenei (tipicamente)
["Mario", "Anna", "Luca"]
- Collezione proprietà
- Accesso per chiave (nome)
- Dati strutturati
{nome: "Mario", età: 30}
🎨 Creazione Oggetti
Il modo più comune e leggibile per creare oggetti.
// Oggetto vuoto
let oggetto = {};
// Oggetto con proprietà
let persona = {
nome: "Mario",
cognome: "Rossi",
età: 30,
professione: "Sviluppatore"
};
// Oggetto complesso con proprietà di vari tipi
let prodotto = {
id: 1001,
nome: "Laptop",
prezzo: 999.99,
disponibile: true,
categorie: ["elettronica", "computer"],
specifiche: {
cpu: "Intel i7",
ram: "16GB",
storage: "512GB SSD"
}
};
console.log(persona); // {nome: "Mario", cognome: "Rossi", età: 30, ...}
Costruttore esplicito, ma meno leggibile.
let persona = new Object();
persona.nome = "Mario";
persona.età = 30;
console.log(persona); // {nome: "Mario", età: 30}
// ✅ Meglio usare object literal
let personaMigliore = {
nome: "Mario",
età: 30
};
Crea oggetto con prototipo specifico.
// Oggetto prototipo
let personaBase = {
saluta: function() {
return `Ciao, sono ${this.nome}`;
}
};
// Crea oggetto che eredita da personaBase
let mario = Object.create(personaBase);
mario.nome = "Mario";
console.log(mario.saluta()); // "Ciao, sono Mario"
Le chiavi delle proprietà possono contenere spazi o caratteri speciali,
ma vanno racchiuse tra apici.
let oggetto = {
nome: "Mario", // Chiave normale
"data di nascita": "1994-03-15", // Chiave con spazi
"user-id": 12345, // Chiave con trattino
123: "numero come chiave" // Chiave numerica (convertita a stringa)
};
console.log(oggetto.nome); // "Mario"
console.log(oggetto["data di nascita"]); // "1994-03-15"
console.log(oggetto["user-id"]); // 12345
console.log(oggetto[123]); // "numero come chiave"
🔑 Accesso alle Proprietà
Il modo più comune e leggibile.
let persona = {
nome: "Mario",
cognome: "Rossi",
età: 30,
indirizzo: {
via: "Via Roma 1",
città: "Milano",
cap: "20100"
}
};
// Accesso semplice
console.log(persona.nome); // "Mario"
console.log(persona.cognome); // "Rossi"
// Accesso a oggetti annidati
console.log(persona.indirizzo.città); // "Milano"
console.log(persona.indirizzo.via); // "Via Roma 1"
// Proprietà inesistente
console.log(persona.telefono); // undefined
Più flessibile, permette chiavi dinamiche e con spazi.
let persona = {
nome: "Mario",
cognome: "Rossi",
"data di nascita": "1994-03-15"
};
// Accesso base
console.log(persona["nome"]); // "Mario"
console.log(persona["cognome"]); // "Rossi"
// Chiavi con spazi (SOLO con bracket notation)
console.log(persona["data di nascita"]); // "1994-03-15"
// Chiavi dinamiche
let prop = "nome";
console.log(persona[prop]); // "Mario"
// Chiavi calcolate
let chiave = "co" + "gnome";
console.log(persona[chiave]); // "Rossi"
| Caratteristica | Dot Notation | Bracket Notation |
|---|---|---|
| Sintassi | obj.prop |
obj["prop"] |
| Leggibilità | ⭐⭐⭐ Alta | ⭐⭐ Media |
| Chiavi con spazi | ❌ No | ✅ Sì |
| Chiavi dinamiche | ❌ No | ✅ Sì |
| Quando usare | Default (80% casi) | Chiavi dinamiche/speciali |
let persona = {
nome: "Mario",
indirizzo: {
città: "Milano"
}
};
// ❌ SENZA optional chaining (rischio errore)
console.log(persona.contatti.email); // TypeError! contatti è undefined
// ✅ CON optional chaining
console.log(persona.contatti?.email); // undefined (nessun errore)
console.log(persona.indirizzo?.città); // "Milano"
// Molto utile con dati incerti (API, database)
let utente = getUser(); // Potrebbe essere null
console.log(utente?.nome?.toUpperCase());
✏️ Modificare e Aggiungere Proprietà
let persona = {
nome: "Mario",
età: 30,
professione: "Sviluppatore"
};
// Modifica con dot notation
persona.età = 31;
persona.professione = "Senior Developer";
console.log(persona);
// {nome: "Mario", età: 31, professione: "Senior Developer"}
// Modifica con bracket notation
persona["età"] = 32;
console.log(persona.età); // 32
let persona = {
nome: "Mario",
età: 30
};
// Aggiungi proprietà
persona.cognome = "Rossi";
persona.città = "Milano";
persona.hobbies = ["calcio", "lettura", "coding"];
console.log(persona);
// {nome: "Mario", età: 30, cognome: "Rossi", città: "Milano", hobbies: [...]}
let persona = {
nome: "Mario",
età: 30,
temp: "da rimuovere"
};
// Rimuovi proprietà
delete persona.temp;
delete persona.età;
console.log(persona); // {nome: "Mario"}
// Verifica esistenza proprietà
console.log("età" in persona); // false
console.log("nome" in persona); // true
Gli oggetti possono essere modificati anche se dichiarati con const.
const impedisce solo la riassegnazione della variabile!
const persona = {
nome: "Mario",
età: 30
};
// ✅ Modificare proprietà è OK
persona.età = 31;
persona.cognome = "Rossi";
console.log(persona); // {nome: "Mario", età: 31, cognome: "Rossi"}
// ❌ Riassegnare variabile NON è OK
// persona = {nome: "Luigi"}; // TypeError!
⚙️ Metodi negli Oggetti
Un metodo è una funzione salvata come proprietà di un oggetto.
I metodi definiscono i “comportamenti” dell’oggetto.
Funzione come valore di proprietà.
let persona = {
nome: "Mario",
cognome: "Rossi",
età: 30,
// Metodo classico
saluta: function() {
return "Ciao, sono " + this.nome;
},
// Metodo con parametri
presenta: function(lavoro) {
return `Mi chiamo ${this.nome} e sono ${lavoro}`;
}
};
// Chiamata metodi
console.log(persona.saluta());
// "Ciao, sono Mario"
console.log(persona.presenta("sviluppatore"));
// "Mi chiamo Mario e sono sviluppatore"
Modo più moderno e conciso. ⭐ CONSIGLIATO
let persona = {
nome: "Mario",
cognome: "Rossi",
età: 30,
// Sintassi abbreviata (senza 'function')
saluta() {
return `Ciao, sono ${this.nome}`;
},
nomeCompleto() {
return `${this.nome} ${this.cognome}`;
},
compieAnni() {
this.età++;
return `Adesso ho ${this.età} anni!`;
}
};
console.log(persona.saluta()); // "Ciao, sono Mario"
console.log(persona.nomeCompleto()); // "Mario Rossi"
console.log(persona.compieAnni()); // "Adesso ho 31 anni!"
this si riferisce all’oggetto corrente.
let contoBancario = {
titolare: "Mario Rossi",
saldo: 1000,
deposita(importo) {
this.saldo += importo;
return `Depositati €${importo}. Nuovo saldo: €${this.saldo}`;
},
preleva(importo) {
if (importo > this.saldo) {
return "Saldo insufficiente!";
}
this.saldo -= importo;
return `Prelevati €${importo}. Nuovo saldo: €${this.saldo}`;
},
mostraSaldo() {
return `Conto di ${this.titolare}: €${this.saldo}`;
}
};
console.log(contoBancario.mostraSaldo()); // "Conto di Mario Rossi: €1000"
console.log(contoBancario.deposita(500)); // "Depositati €500. Nuovo saldo: €1500"
console.log(contoBancario.preleva(300)); // "Prelevati €300. Nuovo saldo: €1200"
Le arrow functions NON hanno il proprio this.
Evitale per metodi di oggetti!
let persona = {
nome: "Mario",
// ❌ MALE: arrow function
salutaMale: () => {
return `Ciao, sono ${this.nome}`; // this è undefined!
},
// ✅ BENE: function normale
salutaBene() {
return `Ciao, sono ${this.nome}`; // this funziona!
}
};
console.log(persona.salutaMale()); // "Ciao, sono undefined"
console.log(persona.salutaBene()); // "Ciao, sono Mario"
🔁 Iterare sugli Oggetti
Restituisce array con tutte le chiavi.
let persona = {
nome: "Mario",
età: 30,
professione: "Sviluppatore",
città: "Milano"
};
let chiavi = Object.keys(persona);
console.log(chiavi);
// ["nome", "età", "professione", "città"]
// Conta proprietà
console.log(`L'oggetto ha ${chiavi.length} proprietà`);
// Itera sulle chiavi
chiavi.forEach(chiave => {
console.log(`${chiave}: ${persona[chiave]}`);
});
// nome: Mario
// età: 30
// professione: Sviluppatore
// città: Milano
Restituisce array con tutti i valori.
let persona = {
nome: "Mario",
età: 30,
professione: "Sviluppatore"
};
let valori = Object.values(persona);
console.log(valori);
// ["Mario", 30, "Sviluppatore"]
// Somma valori numerici
let punteggi = {
matematica: 28,
fisica: 27,
informatica: 30
};
let voti = Object.values(punteggi);
let somma = voti.reduce((acc, voto) => acc + voto, 0);
let media = somma / voti.length;
console.log(`Media: ${media}`); // Media: 28.333...
Restituisce array di array [chiave, valore].
let persona = {
nome: "Mario",
età: 30,
professione: "Sviluppatore"
};
let entries = Object.entries(persona);
console.log(entries);
// [["nome", "Mario"], ["età", 30], ["professione", "Sviluppatore"]]
// Itera con destructuring
entries.forEach(([chiave, valore]) => {
console.log(`${chiave} = ${valore}`);
});
// nome = Mario
// età = 30
// professione = Sviluppatore
// Converti oggetto in Map
let map = new Map(entries);
console.log(map.get("nome")); // "Mario"
Itera direttamente sulle chiavi.
let persona = {
nome: "Mario",
età: 30,
professione: "Sviluppatore"
};
// for...in itera sulle chiavi
for (let chiave in persona) {
console.log(`${chiave}: ${persona[chiave]}`);
}
// nome: Mario
// età: 30
// professione: Sviluppatore
// Filtra solo stringhe
for (let chiave in persona) {
if (typeof persona[chiave] === "string") {
console.log(persona[chiave]);
}
}
// Mario
// Sviluppatore
| Metodo | Restituisce | Uso Tipico |
|---|---|---|
Object.keys() |
Array chiavi | Conta proprietà, verifica esistenza |
Object.values() |
Array valori | Somme, medie, operazioni sui valori |
Object.entries() |
Array [chiave, valore] | Conversioni, destructuring |
for...in |
– | Iterazione diretta |
📋 Copiare e Unire Oggetti
let originale = {
nome: "Mario",
età: 30
};
// Copia shallow (primo livello)
let copia = { ...originale };
copia.età = 31;
console.log(originale.età); // 30 (invariato)
console.log(copia.età); // 31
// Unione oggetti
let base = { nome: "Mario", età: 30 };
let extra = { professione: "Sviluppatore", città: "Milano" };
let completo = { ...base, ...extra };
console.log(completo);
// {nome: "Mario", età: 30, professione: "Sviluppatore", città: "Milano"}
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
// Unisce obj2 in obj1 (modifica obj1!)
Object.assign(obj1, obj2);
console.log(obj1); // {a: 1, b: 3, c: 4}
// Copia senza modificare originale
let copia = Object.assign({}, obj1);
// Unione multipla
let finale = Object.assign({}, obj1, obj2, { d: 5 });
console.log(finale); // {a: 1, b: 3, c: 4, d: 5}
Spread e Object.assign fanno copie superficiali (shallow):
oggetti annidati sono ancora riferimenti!
let originale = {
nome: "Mario",
indirizzo: {
città: "Milano"
}
};
// Shallow copy
let copia = { ...originale };
// Modifica oggetto annidato
copia.indirizzo.città = "Roma";
console.log(originale.indirizzo.città); // "Roma" (MODIFICATO!)
// ✅ Deep copy con JSON (limitato)
let deepCopy = JSON.parse(JSON.stringify(originale));
// ✅ Deep copy con structuredClone (moderno)
let deepCopy2 = structuredClone(originale);
🚀 Esempio Completo: Sistema Gestione Libri
let libro = {
// Proprietà
titolo: "Il Grande Gatsby",
autore: "F. Scott Fitzgerald",
anno: 1925,
pagine: 180,
genere: "Fiction",
letto: false,
voto: null,
// Metodo: Info completa
infoCompleta() {
return `"${this.titolo}" di ${this.autore} (${this.anno}) - ${this.genere} - ${this.pagine} pagine`;
},
// Metodo: Leggi libro
leggiLibro() {
this.letto = true;
return `✅ Hai letto "${this.titolo}"`;
},
// Metodo: Valuta libro
valuta(voto) {
if (voto < 1 || voto > 5) {
return "❌ Voto deve essere tra 1 e 5";
}
if (!this.letto) {
return "⚠️ Devi prima leggere il libro!";
}
this.voto = voto;
return `⭐ Hai dato ${voto} stelle a "${this.titolo}"`;
},
// Metodo: Tempo lettura stimato
tempoLettura() {
let minutiTotali = this.pagine * 2; // 2 min/pagina
let ore = Math.floor(minutiTotali / 60);
let minuti = minutiTotali % 60;
return `⏱️ Tempo lettura stimato: ${ore}h ${minuti}min`;
},
// Metodo: Stato lettura
statoLettura() {
if (!this.letto) {
return "📚 Da leggere";
}
if (this.voto) {
return `✅ Letto - Voto: ${"⭐".repeat(this.voto)}`;
}
return "✅ Letto - Non valutato";
},
// Metodo: Riepilogo
riepilogo() {
return `
╔═══════════════════════════════════════════╗
║ SCHEDA LIBRO ║
╠═══════════════════════════════════════════╣
║ Titolo: ${this.titolo.padEnd(31)} ║
║ Autore: ${this.autore.padEnd(31)} ║
║ Anno: ${this.anno}${' '.repeat(27)} ║
║ Genere: ${this.genere.padEnd(31)} ║
║ Pagine: ${this.pagine}${' '.repeat(27)} ║
║ Stato: ${this.statoLettura().padEnd(31)} ║
║ ${this.tempoLettura().padEnd(41)} ║
╚═══════════════════════════════════════════╝
`.trim();
}
};
// ===== TEST =====
console.log(libro.infoCompleta());
console.log(libro.tempoLettura());
console.log(libro.statoLettura());
console.log("\n" + libro.leggiLibro());
console.log(libro.valuta(5));
console.log("\n" + libro.riepilogo());
- Proprietà di vari tipi (string, number, boolean, null)
- Metodi con e senza parametri
thisper accedere a proprietà interne- Template literals per formattazione
- Validazione input nei metodi
- Calcoli (tempo lettura)
- Logica condizionale (stato lettura)
- Formattazione avanzata (box ASCII)
💪 Esercizi Pratici
📝 Esercizio 1: Calcolatrice Oggetto
Obiettivo: Crea un oggetto calcolatrice con metodi per operazioni
Requisiti:
- Proprietà
risultatoinizializzata a 0 - Metodo
somma(n) - Metodo
sottrai(n) - Metodo
moltiplica(n) - Metodo
dividi(n)(con controllo divisione per 0) - Metodo
reset()per azzerare - Metodo
mostraRisultato()
📝 Esercizio 2: Gestione Prodotto E-commerce
Obiettivo: Crea oggetto prodotto con gestione stock e prezzo
Requisiti:
- Proprietà: id, nome, prezzo, quantitàStock, categoria
- Metodo
prezzoScontato(percentuale) - Metodo
isDisponibile() - Metodo
aggiungiStock(quantità) - Metodo
rimuoviStock(quantità)con validazione - Metodo
schedaProdotto()con tutte le info
📝 Esercizio 3: Registro Studenti
Obiettivo: Crea oggetto studente con gestione voti
Requisiti:
- Proprietà: nome, cognome, matricola, voti (array vuoto)
- Metodo
aggiungiVoto(materia, voto) - Metodo
calcolaMedia() - Metodo
mostraVoti() - Metodo
votoMassimo()evotoMinimo()
- {} literal
- new Object()
- Object.create()
- obj.prop (dot)
- obj[“prop”] (bracket)
- obj?.prop (optional)
- Funzioni in oggetti
- Keyword this
- Sintassi ES6
- Object.keys()
- Object.values()
- Object.entries()
- for…in
Lezione 6 del Corso JavaScript Completo