mardi 28 avril 2020

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. Now I need to access a private member of the Node class from the SingleLinkedList class but outside I would this wasn't possible; in this way I can return a Node instance from SingleLinkedList and the users can't accede all the data structure with that Node. 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?

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;
         }

         pop() {
            if (this.isEmpty())
               return null;

            let current = this.#head;
            let newTail = current;
            while (current.next) {
               newTail = current;
               current = current.next;
            }
            this.#tail = newTail;
            this.#tail.next = null;
            --this.#size;
            if (this.isEmpty()) { //There was only 1 element
               this.#head = null;
               this.#tail = null;
            }
            return current.value;
         }

         //Remove one element from the head
         shift(){
            if(this.isEmpty())
               return null;

            let val = this.#head.value;
            this.#head = this.#head.next;
            this.#size--;
            return val;
         }

         //Insert the passed element in head
         unshift(value){
            let currentHead = this.#head;
            this.#head = new Node(value);
            this.#head.next = currentHead;
            this.#size++;
            return this; //allow multiple call
         }

         //Return the element at the specified index
         get(index){
            if(index<0 || index>=this.#size)
               return null;

            let current = this.#head;


            return current.value;
         }

         //Set the item at specified index with the specified value
         //Return a boolean value
         set(index,value){
            if(index<0 || index>=this.#size)
               return false;

            let current = this.#head;
            for(let i=0 ; i<index ; current = current.next,++i)
               ;
            //At the end of the above for current will contain the right node
            current.value = value;
            return true;    
         }

         //Insert the node with the specified value at the
         //position(if index === 2 insert the node between the second and
         //the thirth node). Return a boolean
         insert(index,value){
            if(index <0 || index > this.#size)
               return false;
            if(index===0)
               this.unshift(value);
            if(index===this.#size)
               this.push(value);


         }
         // generator to return the values
         *[Symbol.iterator]() {
            for (let current = this.#head; current; current = current.next) {
               yield current.value;
            }
         }

         // the values of each node
         toString() {
            return [...this].join(' ');
         }
      }

      const myLinkedList = new SingleLinkedList();
      myLinkedList.push(3).push(5);
      console.log(myLinkedList.toString());

For example if I make private the nextproperty of the class Node
I can't anymore access the variable inside my 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. Does it exist some , possibly simple, solution in Javascript?

Aucun commentaire:

Enregistrer un commentaire