如何在 JavaScript 中从父类访问私有字段?

Sof*_*123 2 javascript oop private class

我有一个具有私有values字段的堆类。这很好,因为我不希望任何人能够直接修改values.

class Heap {
  
  #values;
  
  constructor(array = []) {
    this.#values = array;
  }

    insert(item) {
    this.#values.push(item);
    this.#bubbleUp(this.#values.length - 1);
  }
}
Run Code Online (Sandbox Code Playgroud)

但现在我想将我的 Heap 类扩展为 PriorityQueue 子类。在此类中,我需要更改某些方法的签名(例如insert),以便为值分配优先级。但是,我无法弄清楚如何values从基类访问该字段。例如,给定以下 PriorityQueue 类:

class PriorityQueue extends Heap {
  
  constructor(array = []) {
    super(array);
  }
  
  insert(item, priority) {

    // Error: Private field '#values' must be declared in an enclosing class
    this.#values.push({ item, priority }); 
    this.#bubbleUp(this.#values.length - 1);
  }
}
Run Code Online (Sandbox Code Playgroud)

尝试将值推送到 时出现错误values

有什么办法可以解决这个问题吗?我想在基类中将字段设为私有,但子类仍然可以访问。

谢谢!

Ber*_*rgi 6

\n

我无法弄清楚如何values从基类访问该字段。

\n
\n

这不可能。Private在JS中真正的意思是私有的。如果您希望该字段可以在类外部访问,请不要使用它。

\n
\n

我想在基类中将字段设为私有,但子类仍然可以访问。

\n
\n

那将是一个受保护的成员,JS 不支持。

\n
\n

有什么办法可以解决这个问题吗?

\n
\n

好吧,您实际上不需要访问.#values. 您需要做的就是调用基类insert方法:

\n
class PriorityQueue extends Heap { \n  insert(item, priority) {\n    super.insert({ item, priority });\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我想将我的Heap类扩展为PriorityQueue子类。在此类中,我需要更改某些方法的签名(例如插入),以便为值分配优先级。

\n
\n

这是一个坏主意。子类不应该改变方法签名,否则会违反里氏替换原则。相反,使用组合而不是继承,其中优先级队列具有包含堆:

\n
class PriorityQueue {\n  #heap = new Heap(v => v.priority); // assuming it takes a custom comparator?\n  \n  push(item, priority) {\n    this.#heap.insert({ item, priority });\n  }\n  pop() {\n    return this.#heap.\xe2\x80\xa6\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n