🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Esercizi Symbol JavaScript

Codegrind Team•Jul 12 2024

Ecco degli esercizi con soluzione per praticare l’uso dei Symbol in JavaScript.

Esercizio 1: Creare e Utilizzare un Symbol

Creare un Symbol e utilizzarlo come chiave di una proprietĂ  di un oggetto.
const mySymbol = Symbol("mySymbol");
const obj = {
  [mySymbol]: "valore associato al simbolo",
};

console.log(obj[mySymbol]); // valore associato al simbolo

Esercizio 2: Symbol Unici

Dimostrare che i Symbol sono unici.
const symbol1 = Symbol("test");
const symbol2 = Symbol("test");

console.log(symbol1 === symbol2); // false

Esercizio 3: Symbol in un Oggetto

Aggiungere un Symbol come chiave di un oggetto e iterare sull'oggetto.
const mySymbol = Symbol("mySymbol");
const obj = {
  [mySymbol]: "valore associato al simbolo",
  normale: "valore normale",
};

for (let key in obj) {
  console.log(key); // normale
}

console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol(mySymbol) ]

Esercizio 4: Symbol.for e Symbol.keyFor

Utilizzare `Symbol.for` per creare e recuperare Symbol globali e `Symbol.keyFor` per ottenere la chiave di un Symbol globale.
const globalSymbol = Symbol.for("globalSymbol");
const sameGlobalSymbol = Symbol.for("globalSymbol");

console.log(globalSymbol === sameGlobalSymbol); // true
console.log(Symbol.keyFor(globalSymbol)); // globalSymbol

Esercizio 5: Symbol come ProprietĂ  Privata

Utilizzare Symbol per simulare proprietĂ  private in una classe.
const _saldo = Symbol("saldo");

class ContoBancario {
  constructor() {
    this[_saldo] = 0;
  }

  deposita(importo) {
    if (importo > 0) {
      this[_saldo] += importo;
    }
  }

  getSaldo() {
    return this[_saldo];
  }
}

const conto = new ContoBancario();
conto.deposita(100);
console.log(conto.getSaldo()); // 100
console.log(conto._saldo); // undefined

Esercizio 6: Iteratori e Symbol.iterator

Creare un iteratore personalizzato utilizzando `Symbol.iterator`.
const iterableObj = {
  data: [1, 2, 3],
  [Symbol.iterator]: function () {
    let index = 0;
    const data = this.data;
    return {
      next: function () {
        if (index < data.length) {
          return { value: data[index++], done: false };
        } else {
          return { done: true };
        }
      },
    };
  },
};

for (let value of iterableObj) {
  console.log(value); // 1, 2, 3
}

Esercizio 7: Symbol.toPrimitive

Utilizzare `Symbol.toPrimitive` per personalizzare la conversione di un oggetto in un valore primitivo.
const obj = {
  valore: 100,
  [Symbol.toPrimitive](hint) {
    if (hint === "number") {
      return this.valore;
    }
    return null;
  },
};

console.log(+obj); // 100
console.log(`${obj}`); // null

Esercizio 8: Symbol.toStringTag

Utilizzare `Symbol.toStringTag` per personalizzare il risultato di `Object.prototype.toString`.
const myObject = {
  [Symbol.toStringTag]: "MyCustomObject",
};

console.log(Object.prototype.toString.call(myObject)); // [object MyCustomObject]

Esercizio 9: Symbol.species

Utilizzare `Symbol.species` per personalizzare la costruzione di sottoclassi di oggetti incorporati.
class MyArray extends Array {
  static get [Symbol.species]() {
    return Array;
  }
}

const arr = new MyArray(1, 2, 3);
const mappedArr = arr.map((x) => x * x);

console.log(mappedArr instanceof MyArray); // false
console.log(mappedArr instanceof Array); // true

Esercizio 10: Symbol.isConcatSpreadable

Utilizzare `Symbol.isConcatSpreadable` per controllare se un oggetto deve essere espanso durante la concatenazione degli array.
const arrayLike = {
  length: 2,
  0: "a",
  1: "b",
  [Symbol.isConcatSpreadable]: true,
};
const result = ["start"].concat(arrayLike, "end");

console.log(result); // ['start', 'a', 'b', 'end']