如何从 JavaScript 中的父类访问私有字段?
Posted
技术标签:
【中文标题】如何从 JavaScript 中的父类访问私有字段?【英文标题】:How to access private fields from parent class in JavaScript? 【发布时间】:2021-12-15 19:02:38 【问题描述】:我有一个 Heap 类,它有一个私有 values
字段。这很好,因为我不希望任何人能够直接修改values
。
class Heap
#values;
constructor(array = [])
this.#values = array;
insert(item)
this.#values.push(item);
this.#bubbleUp(this.#values.length - 1);
但现在我想将我的 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);
尝试将值推送到 values
时出现错误。
有没有办法解决这个问题?我想在基类中将一个字段设为私有,但子类仍然可以访问。
谢谢!
【问题讨论】:
只调用父级的insert
方法? super.insert( item, priority )
.
“我想在基类中将一个字段设为私有,但子类仍然可以访问。”这就是受保护的访问。但是,JS 目前还没有。所以你想在子类中使用的任何东西都必须是公开的。
【参考方案1】:
我不知道如何从基类访问
values
字段。
这是不可能的。私有在 JS 中真正意味着私有。如果您希望该字段可在课堂外访问,请不要使用它。
我想在基类中将一个字段设为私有,但子类仍然可以访问。
这将是一个受保护的成员,JS 不支持。
有没有办法解决这个问题?
好吧,您实际上并不需要访问.#values
。您需要做的就是调用基类insert
方法:
class PriorityQueue extends Heap
insert(item, priority)
super.insert( item, priority );
我想将我的
Heap
类扩展为PriorityQueue
子类。在这个类中,我需要更改一些方法的签名(例如插入),以便它为一个值分配优先级。
这是个坏主意。子类不应更改方法签名,否则将违反Liskov substitution principle。相反,请使用composition over inheritance,其中优先级队列具有或包含堆:
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.…
【讨论】:
感谢您的回答,您的帖子很有帮助。我的Heap
类确实使用了比较器。我什至从未考虑过将 PriorityQueue 构造为具有堆实例,而不是从 Heap 类继承。我显然有很多东西要学。顺便说一句,您是否推荐任何书籍来学习诸如组合优于继承之类的主题?以上是关于如何从 JavaScript 中的父类访问私有字段?的主要内容,如果未能解决你的问题,请参考以下文章