1

我正在尝试创建一个堆栈和队列类,但是如果不能使用继承,我就不能将数据字段设为私有。每次尝试时,我都会收到 Uncaught SyntaxError: Private field '#data' must be declared 在封闭类错误中。如何让子类继承私有字段?下面的代码:

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()
  }
}

4

1 回答 1

0

一种可能的解决方法是将扩展类和原型方法与私有字段和受保护数据保持在一起,WeakMap因为无论实际继承如何,都可以利用每个实例化的单个共享引用。

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; }

于 2022-02-24T18:13:17.387 回答