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!

🎯 Array vs Oggetti

Array

  • Lista ordinata
  • Accesso per indice numerico
  • Elementi omogenei (tipicamente)
  • ["Mario", "Anna", "Luca"]
Oggetti

  • Collezione proprietà
  • Accesso per chiave (nome)
  • Dati strutturati
  • {nome: "Mario", età: 30}

🎨 Creazione Oggetti

1
Object Literal (Consigliato)

Il modo più comune e leggibile per creare oggetti.

Creazione con {}
// 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, ...}

2
new Object() (Meno Usato)

Costruttore esplicito, ma meno leggibile.

Creazione con new Object()
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
};

3
Object.create() (Avanzato)

Crea oggetto con prototipo specifico.

Object.create()
// 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"

💡 Proprietà Speciali

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à

1
Dot Notation (Notazione Punto)

Il modo più comune e leggibile.

Accesso con .
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

2
Bracket Notation (Notazione Parentesi Quadre)

Più flessibile, permette chiavi dinamiche e con spazi.

Accesso con []
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"

📊 Dot vs Bracket Notation

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

Optional Chaining (?.) – ES2020
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à

Modificare Proprietà Esistenti
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

Aggiungere Nuove Proprietà
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: [...]}

Rimuovere Proprietà (delete)
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

⚠️ Oggetti Sono Mutabili!

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.

1
Metodi – Sintassi Classica

Funzione come valore di proprietà.

Metodi Classici
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"

2
Metodi – Sintassi Abbreviata (ES6)

Modo più moderno e conciso. ⭐ CONSIGLIATO

Sintassi ES6
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!"

3
La Keyword this

this si riferisce all’oggetto corrente.

Uso di this
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"

⚠️ Attenzione con Arrow Functions!

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

1
Object.keys() – Array delle Chiavi

Restituisce array con tutte le chiavi.

Object.keys()
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

2
Object.values() – Array dei Valori

Restituisce array con tutti i valori.

Object.values()
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...

3
Object.entries() – Array di Coppie [chiave, valore]

Restituisce array di array [chiave, valore].

Object.entries()
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"

4
for…in Loop

Itera direttamente sulle chiavi.

Loop for…in
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

📊 Confronto Metodi Iterazione

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

Shallow Copy con Spread Operator (…)
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"}

Object.assign()
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}

⚠️ Shallow vs Deep Copy

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

Oggetto Libro Completo
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());

💡 Tecniche Usate
  • Proprietà di vari tipi (string, number, boolean, null)
  • Metodi con e senza parametri
  • this per 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à risultato inizializzata 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() e votoMinimo()

🎯 Riepilogo Lezione

Creazione:

  • {} literal
  • new Object()
  • Object.create()
Accesso:

  • obj.prop (dot)
  • obj[“prop”] (bracket)
  • obj?.prop (optional)
Metodi:

  • Funzioni in oggetti
  • Keyword this
  • Sintassi ES6
Iterazione:

  • Object.keys()
  • Object.values()
  • Object.entries()
  • for…in

Lezione 6 del Corso JavaScript Completo

Torna in alto