簡體   English   中英

僅在具有該 class 實例的 class 內部訪問 class 的私有成員

[英]Access to private member of a class only inside a class that has an instance of that class

我正在實施一個鏈接列表。 我有兩個類NodeSingleLinkedList 現在我需要從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 Nodenext屬性設為私有
我無法再訪問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 內,所以效果很好。

如果你不希望它們嵌套,你可以讓SingleLinkedListNode提供一個 function ,只有Node可以訪問它,這將使NodeSingleLinkedlist的私有字段中獲取信息。 舉個例子,看評論:

 "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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM