如何从 JavaScript 中的父 class 访问私有字段?

How to access private fields from parent class in JavaScript?

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

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

    insert(item) {
    this.#values.push(item);
    this.#bubbleUp(this.#values.length - 1);
  }
}

但现在我想将我的 Heap class 扩展到 PriorityQueue subclass。在这个 class 中,我需要更改一些方法的签名(例如 insert),以便它为一个值分配优先级。但是,我不知道如何从基础 class 访问 values 字段。例如,给定以下 PriorityQueue class:

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

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

有什么办法可以解决这个问题吗?我想在基础 class 中将一个字段设为私有,但子 class.

仍然可以访问

谢谢!

I cannot figure out how to access the values field from the base class.

这是不可能的。 private 在 JS 中真正的意思是私有。如果您希望该字段可以在 class.

之外访问,请不要使用它

I want to make a field private in the base class, but still accessible to the subclass.

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

Is there any way around this problem?

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

class PriorityQueue extends Heap { 
  insert(item, priority) {
    super.insert({ item, priority });
  }
}

I would like to extend my Heap class into a PriorityQueue subclass. In this class I need to change the signature of some of the methods (for example insert) so that it assigns a priority to a value.

这是个坏主意。 subclass 不应更改方法签名,否则会违反 Liskov substitution principle. Instead, use composition over inheritance,其中优先级队列 hascontains一个堆:

class PriorityQueue {
  #heap = new Heap(v => v.priority); // assuming it takes a custom comparator?
  
  push(item, priority) {
    this.#heap.insert({ item, priority });
  }
  pop() {
    return this.#heap.…
  }
}