Estoy tratando de hacer clases de pila y cola, pero no puedo hacer que el campo de datos sea privado sin poder usar la herencia. Obtengo un SyntaxError no capturado: el campo privado '#data' debe declararse en un error de clase adjunto cada vez que lo intento. ¿Cómo puedo hacer que las subclases hereden el campo privado? código a continuación:
class Datalist { #data constructor() { this.#data = Array.from(arguments) return this.#data } valueOf() { return this.#data } get size() { return this.#data.length } peek() { if (this.size > 0) { return this.#data[0] } else { return null } } } class Queue extends Datalist { constructor() { super(arguments) } enqueue() { this.#data = this.#data.concat(arguments) } dequeue() { return this.#data.shift() } } class Stack extends Datalist { constructor() { super(arguments) this.#data = this.#data.reverse() } push() { this.#data = this.#data.splice(0, 0, Array.from(...arguments).reverse) } pop() { return this.#data.shift() } }Una posible solución alternativa que mantenga el enfoque de clases extendidas y métodos prototípicos junto con campos privados y datos protegidos podría basarse en WeakMap porque se puede aprovechar el trabajo con una única referencia compartida para cada instancia, independientemente de la herencia real.
const privateListLookup = new WeakMap; const getPrivateList = reference => privateListLookup.get(reference); const getClone = value => (typeof structuredClone === 'function') ? structuredClone(value) : JSON.parse(JSON.stringify(value)); // const getCopy = value => [...value]; class DataList { constructor(...list) { // enable shared privacy via an instance's // `this` reference and a weak map. privateListLookup.set(this, list); } valueOf() { // ensure data protection by not exposing // the private `list` reference directly. return getClone(getPrivateList(this)); // // make a decision, clone or shallow copy. // return getCopy(getPrivateList(this)); } toString() { return String(getPrivateList(this)); } // toJSON() { // return JSON.stringify(getPrivateList(this)); // } get size() { return getPrivateList(this).length; } peek() { return (this.size > 0) // ? getPrivateList(this).at(0) ? getPrivateList(this)[0] : null; } } class Queue extends DataList { constructor(...args) { super(...args); } enqueue(...args) { getPrivateList(this).push(...args); } dequeue() { return getPrivateList(this).shift(); } } class Stack extends DataList { constructor(...args) { super(...args); getPrivateList(this).reverse(); } push(...args) { getPrivateList(this).push(...args); } pop() { return getPrivateList(this).pop(); } } const queue = new Queue(...['the', 'quick', 'brown', 'fox']); const stack = new Stack('jumps', 'over', 'the', 'lazy', 'dog'); console.log({ queue: queue.valueOf(), stack: stack.valueOf(), }); console.log({ queue: queue.toString(), stack: stack.toString(), }); console.log( 'queue.enqueue(stack.pop()) ...' ); queue.enqueue(stack.pop()); console.log({ queue: queue.toString(), stack: stack.toString(), }); console.log( 'queue.enqueue(stack.pop(), stack.pop()) ...' ); queue.enqueue(stack.pop(), stack.pop()); console.log({ queue: queue.toString(), stack: stack.toString(), }); console.log( 'stack.peek() ...', stack.peek() ) console.log( 'stack.push(queue.dequeue(), queue.dequeue()) ...' ); stack.push(queue.dequeue(), queue.dequeue()); console.log({ queue: queue.toString(), stack: stack.toString(), }); console.log({ queue: queue.valueOf(), stack: stack.valueOf(), }); .as-console-wrapper { min-height: 100%!important; top: 0; }