![](/img/trans.png)
[英]Is closure in javascript comparable to an instance of a class(which has a private member and a public method) in c++?
[英]Access to private member of a class only inside a class that has an instance of that class
我正在實施一個鏈接列表。 我有兩個類Node
和SingleLinkedList
。 現在我需要從SingleLinkedList
class 訪問Node
class 的私有成員,但在外面我認為這是不可能的; 通過這種方式,我可以從SingleLinkedList
返回一個Node
實例,並且用戶無法使用該 Node 加入所有數據結構。 In Java when a class has a object of another class (composition) can do this, in C++ there are friend classes. 如何在 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);
例如,如果我將 class Node
的next
屬性設為私有
我無法再訪問SingleLinkedClass
中的變量。 相反,如果我留下這樣的代碼並從某個 function 返回一個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()
返回節點時不再是問題,因為 class Node
的成員#next
是私有的,但這樣我有一個錯誤,因為即使在SingleLinkedClass
內部,成員#next
是t 可見。
我希望這能澄清我的問題
私有標識符是詞法范圍的,因此#size
等在SingleLinkedList
之外是不可訪問的。 但是有幾種方法可以做到這一點。
最簡單的是在SingleLinkedList
中制作Node
:
"use strict"; class SingleLinkedList { #size = 0; constructor(size) { this.#size = size; } static Node = class Node { example(list) { console.log(`The size of the list is ${list.#size}`); } } } const Node = SingleLinkedList.Node; // The `Node` code has access to `SingleLinkedList`'s private field: const l = new SingleLinkedList(42); const n = new Node(); n.example(l); // "The size of the list is ${getSize(list)}"
由於范圍是詞法的,並且Node
的所有代碼都在SingleLinkedList
的 scope 內,所以效果很好。
如果你不希望它們嵌套,你可以讓SingleLinkedList
為Node
提供一個 function ,只有Node
可以訪問它,這將使Node
從SingleLinkedlist
的私有字段中獲取信息。 舉個例子,看評論:
"use strict"; const {Node, SingleLinkedList} = (() => { // A function SingleLinkedList will fill in let getSize; // Create the class class SingleLinkedList { #size = 0; constructor(size) { this.#size = size; } // This is a temporary function for filling in `getSize` static boot() { getSize = list => list.#size; } } // Fill in `getSize` SingleLinkedList.boot(); delete SingleLinkedList.boot; // Find the `Node` class, which uses `getSize` class Node { example(list) { console.log(`The size of the list is ${getSize(list)}`); } } // Return them; `getSize` is entirely private to the code // in this function, nothing else can use it return {Node, SingleLinkedList} })(); // The `Node` code has access to `SingleLinkedList`'s private field: const l = new SingleLinkedList(42); const n = new Node(); n.example(l); // "The size of the list is ${getSize(list)}"
這是有效的,因為 #size 的實際使用在它存在的#size
內。
另一種選擇是在SingleLinkedList
中制作Node
:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.