只有在一个有该类实例的类中才能访问该类的私有成员。

问题描述 投票:0回答:1

我正在实现一个Linked List.我有两个类,分别是 NodeSingleLinkedList. 现在,我需要访问一个私人成员的。Node 阶层 SingleLinkedList 类,但在外面,我想这是不可能的;这样,我可以返回一个 Node 例子 SingleLinkedList 而用户不能用该Node加入所有的数据结构。在Java中当一个类有了另一个类的对象(composition)就可以做到这一点,在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 是不可见的。

我希望这能澄清我的问题

javascript oop design-patterns es6-class
1个回答
2
投票

私有标识符的范围是词法的,所以 #size 诸如此类 SingleLinkedList. 但有几个方法可以做到这一点。

最简单的方法是让 Node SingleLinkedList:

"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,这样就可以了。

如果你不想让它们嵌套,你可以得到 SingleLinkedList 提供 Node 与函数只 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 是在它存在的范围内。

另一种选择是将 Node SingleLinkedList:

© www.soinside.com 2019 - 2024. All rights reserved.