[英]Access to private member of a class only inside a class that has an instance of that class
I'm implementing a Linked List.我正在实施一个链接列表。 I have two classes Node
and SingleLinkedList
.我有两个类Node
和SingleLinkedList
。 Now I need to access a private member of the Node
class from the SingleLinkedList
class but outside I would this wasn't possible;现在我需要从SingleLinkedList
class 访问Node
class 的私有成员,但在外面我认为这是不可能的; in this way I can return a Node
instance from SingleLinkedList
and the users can't accede all the data structure with that Node.通过这种方式,我可以从SingleLinkedList
返回一个Node
实例,并且用户无法使用该 Node 加入所有数据结构。 In Java when a class has a object of another class (composition) can do this, in C++ there are friend classes. In Java when a class has a object of another class (composition) can do this, in C++ there are friend classes. How can I do this in Javascript?如何在 Javascript 中执行此操作?
The following is a "example toy" that I'm implementing to test my knowledges acquired so far and to see what problems come up以下是我正在实施的“示例玩具”,以测试我迄今为止获得的知识并查看出现了什么问题
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);
For example if I make private the next
property of the class Node
例如,如果我将 class Node
的next
属性设为私有
I can't anymore access the variable inside my SingleLinkedClass
.我无法再访问SingleLinkedClass
中的变量。 Instead if I leave the code like that and I return a Node
instance from some function the user can accede almost all my structure using the next property.相反,如果我留下这样的代码并从某个 function 返回一个Node
实例,则用户可以使用下一个属性加入几乎所有我的结构。 Does it exist some, possibly simple, solution in Javascript? Javascript 中是否存在一些可能很简单的解决方案? I want be as clear as possible.我想尽可能清楚。 Thus here what I want do:因此,我想要做的是:
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
Now,in the code above, the get()
return a node and with it you can to scan the whole list.现在,在上面的代码中, get()
返回一个节点,您可以使用它扫描整个列表。 No good.不好。 Thus I want do:因此我想做:
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
With this last version when I return a Node from get()
isn't any more a problem because the member of class Node
namely #next
is private but in this way I have an error because even inside the SingleLinkedClass
the member #next
isn't visible.在最后一个版本中,当我从get()
返回节点时不再是问题,因为 class Node
的成员#next
是私有的,但这样我有一个错误,因为即使在SingleLinkedClass
内部,成员#next
是t 可见。
I hope this clarify my question我希望这能澄清我的问题
The private identifier is scoped lexically, so #size
and such are inaccessible outside SingleLinkedList
.私有标识符是词法范围的,因此#size
等在SingleLinkedList
之外是不可访问的。 But there are a couple of ways to do it.但是有几种方法可以做到这一点。
The simplest is to make Node
within 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)}"
Since the scoping is lexical, and all of Node
's code is within the scope of SingleLinkedList
, that works just fine.由于范围是词法的,并且Node
的所有代码都在SingleLinkedList
的 scope 内,所以效果很好。
If you don't want them nested, you can get SingleLinkedList
to provide Node
with a function that only Node
has access to that will let Node
get information from a SingleLinkedlist
's private fields.如果你不希望它们嵌套,你可以让SingleLinkedList
为Node
提供一个 function ,只有Node
可以访问它,这将使Node
从SingleLinkedlist
的私有字段中获取信息。 Here's an example, see the comments:举个例子,看评论:
"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)}"
That works because the actual use of #size
is within the scope where it exists.这是有效的,因为 #size 的实际使用在它存在的#size
内。
The other option is to make Node
within SingleLinkedList
:另一种选择是在SingleLinkedList
中制作Node
:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.