Lección 6 · 6 de 20
Miembros estáticos y Symbol · JavaScript
Use static en JavaScript para contadores y métodos factoría de clase, y Symbol para claves únicas y para cambiar cómo se convierte un objeto.

Lo marcado con `static` pertenece a la clase, no a cada objeto. Order.TAX es una constante común a todos los pedidos y static #nextId es un contador privado de la clase: cada new Order lo lee y lo incrementa con Order.#nextId++, así que los pedidos reciben 1, 2 y 3 sin repetirse.
Un método estático se llama sobre la clase: Order.fromLine("Ana;100"). Es un patrón muy común, la factoría: convierte una línea de texto (de un CSV, por ejemplo) en un pedido, separando el cliente y el importe con split.
Un `Symbol` es un valor único que sirve como clave de propiedad. JavaScript define algunos símbolos conocidos que cambian el comportamiento del lenguaje: Symbol.toPrimitive decide en qué se convierte el objeto (en texto dentro de una plantilla, o en el importe con IVA en Number(o), que la suma usa para el total) y Symbol.toStringTag cambia lo que muestra Object.prototype.toString: [object Order].
También puede crear sus propios símbolos: orders[2][internal] guarda un dato que no aparece en Object.keys ni choca con ninguna otra propiedad, porque cada símbolo es distinto (Symbol("id") === Symbol("id") es false). Symbol.for("id"), en cambio, usa un registro global y devuelve siempre el mismo.
Código · main.js
class Order { static #nextId = 1; // belongs to the class, shared by all orders static TAX = 0.21; static fromLine(line) { // static factory: Order.fromLine("Ana;100") const [customer, amount] = line.split(";"); return new Order(customer, Number(amount)); } constructor(customer, amount) { this.id = Order.#nextId++; this.customer = customer; this.amount = amount; } // Well-known symbols change how the language treats the object. get [Symbol.toStringTag]() { return "Order"; } [Symbol.toPrimitive](hint) { if (hint === "number") return this.amount * (1 + Order.TAX); return `Order #${this.id} for ${this.customer}`; }}const orders = ["Ana;100", "Luis;40", "Marta;250"].map((line) => Order.fromLine(line));console.log(`${orders[0]} | ${orders[2]}`);console.log("Total with tax:", orders.reduce((sum, o) => sum + Number(o), 0).toFixed(2));console.log(Object.prototype.toString.call(orders[1]), "| TAX:", Order.TAX);// A Symbol is a unique key: it never clashes with other properties.const internal = Symbol("internal");orders[2][internal] = "priority";console.log("Keys:", Object.keys(orders[2]).join(", "));console.log("Symbol value:", orders[2][internal]);console.log("Unique:", Symbol("id") === Symbol("id"), "| registry:", Symbol.for("id") === Symbol.for("id"));Salida · node main.js
Order #1 for Ana | Order #3 for Marta Total with tax: 471.90 [object Order] | TAX: 0.21 Keys: id, customer, amount Symbol value: priority Unique: false | registry: true
Para recordar
- Los miembros
staticpertenecen a la clase y se usan comoClase.miembro. - Un método estático factoría crea objetos a partir de otros datos.
- Cada
Symbol()es único y sirve como clave que no choca con otras. Symbol.toPrimitiveySymbol.toStringTagcambian cómo se convierte y se muestra un objeto.
Ejercicio
Añada a Order un método estático count() que devuelva cuántos pedidos se han creado (a partir de #nextId) y use un símbolo propio, Symbol("notes"), para guardar una nota en el pedido de Luis.