【发布时间】:2020-04-28 13:52:18
【问题描述】:
我正在实现一个链接列表。
我有两个班级Node 和SingleLinkedList。现在我需要从SingleLinkedList 类访问Node 类的私有成员,但在外面我认为这是不可能的;通过这种方式,我可以从SingleLinkedList 返回一个Node 实例,并且用户无法使用该节点加入所有数据结构。在 Java 中,当一个类具有另一个类的对象(组合)时可以做到这一点,而在 C++ 中则有友元类。我怎样才能在 Javascript 中做到这一点?
以下是我正在实施的“示例玩具”,以测试我目前获得的知识并看看会出现什么问题
class Node {
next = null;
constructor(value) {
this.value = value;
}
}
class SingleLinkedList {
#size = 0;
#head = null;
#tail = null;
// read only get accessor property
get size() {
return this.#size;
}
isEmpty() {
return this.#size === 0;
}
// insert a new Node (in tail) with the desired value
push(value) {
const node = new Node(value);
if (this.isEmpty()) {
this.#head = node;
} else {
this.#tail.next = node;
}
// the following instructions are common to both the cases.
this.#tail = node;
this.#size++;
// to allow multiple push call
return this;
}
get(index){
if(index<0 || index>=this.#size)
return null;
let current = this.#head;
return current.value;
}
}
const myLinkedList = new SingleLinkedList();
myLinkedList.push(3).push(5);
例如,如果我将 Node 类的 nextproperty 设为私有@
我无法再访问我的SingleLinkedClass 中的变量。相反,如果我留下这样的代码并从某个函数返回一个Node 实例,那么用户可以使用下一个属性加入几乎所有我的结构。它是否存在一些可能很简单的 Javascript 解决方案?
我想尽可能清楚。因此,我想要做的是:
class Node {
next = null;
constructor(value) {
this.value = value;
}
}
class SingleLinkedList {
#size = 0;
#head = null;
#tail = null;
// read only get accessor property
get size() {
return this.#size;
}
isEmpty() {
return this.#size === 0;
}
// insert a new Node (in tail) with the desired value
push(value) {
const node = new Node(value);
if (this.isEmpty()) {
this.#head = node;
} else {
this.#tail.next = node;
}
// the following instructions are common to both the cases.
this.#tail = node;
this.#size++;
// to allow multiple push call
return this;
}
get(index){
if(index<0 || index>=this.#size)
return null;
let current = this.#head;
return current; //NOW RETURN A NODE
}
const myLinkedList = new SingleLinkedList();
myLinkedList.push(3).push(5);
const myNode = myLinkedList.get(0); //RETURN NODE
现在,在上面的代码中,get() 返回一个节点,您可以使用它扫描整个列表。不好。因此我想做:
class Node {
#next = null; //PRIVATE MEMBER
constructor(value) {
this.value = value;
}
}
class SingleLinkedList {
#size = 0;
#head = null;
#tail = null;
// read only get accessor property
get size() {
return this.#size;
}
isEmpty() {
return this.#size === 0;
}
// insert a new Node (in tail) with the desired value
push(value) {
const node = new Node(value);
if (this.isEmpty()) {
this.#head = node;
} else {
this.#tail.#next = node; //ERROR
}
// the following instructions are common to both the cases.
this.#tail = node;
this.#size++;
// to allow multiple push call
return this;
}
get(index){
if(index<0 || index>=this.#size)
return null;
let current = this.#head;
return current; //NOW RETURN A NODE
}
}
const myLinkedList = new SingleLinkedList();
myLinkedList.push(3).push(5);
console.log(myLinkedList.toString());
const myNode = myLinkedList.get(0); //RETURN NODE,NO MORE A PROBLEM
在最后一个版本中,当我从 get() 返回一个节点时不再是问题,因为 Node 类的成员,即 #next 是私有的,但这样我有一个错误,因为即使在 @ 987654338@ 成员#next 不可见。
我希望这能澄清我的问题
【问题讨论】:
-
为什么要将
Node(链接列表的内部)返回给用户? -
您能否缩短这些代码示例,以便更早地指出要点并更容易发现您的 sn-ps 之间的差异?
-
@Bergi 从一些函数返回一个节点大大简化了我必须实现的其他函数的实现(可以重用返回节点的函数)。此外,我缩短了一点代码
-
这是关于将节点返回给您自己,而不是返回给用户。您也可以(应该)将这些可重用的辅助方法设为私有。
-
@Bergi 否,因为这些方法既是用户方法又是内部方法。但我希望当他们从我的类 LinkedList 调用时,我可以访问他们的私有成员(节点类,即返回的类型实例),而不是从外部调用它们(用户调用)没有。
标签: javascript oop design-patterns es6-class