Я реализую связанный список. У меня есть два класса Node
и SingleLinkedList
. Теперь мне нужно получить доступ к закрытому члену класса Node
из класса SingleLinkedList
, но снаружи я бы этого не сделал; таким образом я могу вернуть Node
экземпляр из SingleLinkedList
, и пользователи не могут присоединиться ко всей структуре данных с этим узлом. В 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);
Например, если я закрываю свойство next
класса Node
, я больше не могу получить доступ к переменной внутри моего 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
С этой последней версией, когда я возвращаю Node из get()
, больше не проблема, потому что член класса Node
, а именно #next
, является частным, но в таким образом у меня возникает ошибка, потому что даже внутри SingleLinkedClass
член #next
не виден.
Надеюсь, это прояснит мой вопрос