How to design a JS object that has private state and may be instantiated multiple times?

Just trying to wrap my head around prototype-based design

Problem: implement a data structure say priority-queue with a known API. Instantiate multiple instances of the PQ.

So I used the revealing module pattern as follows

module.exports = (function () {
// ... assume the following methods are revealed. Other private methods/fields are hidden
let priorityQueue = {
        insert,
        removeMax,
        isEmpty,
        toString
    };

    return {
        priorityQueue,
        newObj: (comparer, swapper) => {
            let instance = Object.create(priorityQueue);
            instance.array = [];
            instance.size = 0;
            instance.less = comparer;
            instance.swap = swapper;
            return instance;
        }
    }
})();

Created a newObj factory method to create valid instances. priorityQueue is the API/prototype.

  • So methods belong in the prototype.
  • Instance Fields cannot reside there ; they would be shared across instances.

However in this case, the internal fields of the PQ are not encapsulated.

const pQ = require('./priorityQueue').newObj(less, swap);
pQ.array = undefined;    // NOOOOOOO!!!!

So how would that be achieved – another iffe to close over the instance state??

If there are 2 or more levels of subclassing – this looks like it will get messy. Seems like standard fare – am I missing the JS way?

How to design a JS object that has private state and may be instantiated multiple times?