Define 'real' private methods in ES6 Module/Class in a nodejs only environment without any information leak

Megajin picture Megajin · Aug 23, 2017 · Viewed 8.7k times · Source

I know that there is no REAL private method INSIDE ES6 classes. However I was playing around a little bit and discovered something good - maybe...

As I mentioned it is not possible to not expose properties of an object. But I've tried to achieve somewhat of OOP programming as I divided my classes into seperate files and then exported those classes like:

class MyClass {
  constructor() {
    /**
     * Initialize stuff...
     */
  }

  myMethod() {
    /**
     * Do public stuff...
     */
  }

}

// expose class to environment.
export default MyClass;

So I can import the class:

import MyClass from './MyClass.js';

Of course myMethod is accessible from any other file which imported the module. Sinced I was in need of variables and functions beeing accessible only by the class I've tried this:

// private variable outside of class scope but still accessible.
let possiblePrivateVariable = 'am I a private variable?';

class MyClass {
  constructor() {
    /**
    * Initialize stuff...
    */
  }

  myMethod() {
    // run private method.
    console.log(_possiblePrivateMethod());
    // show private variable.
    console.log(possiblePrivateVariable);
  }

}

// private function outside of class scope but still accessible.
function _possiblePrivateMethod() {
  return 'am I a private method?';
}

// expose class to environment.
export default MyClass;

Now you can't access the private variable and private method:

// Import class to newFile.js and use it.
import MyClass from './MyClass.js';

const exposedClass = new MyClass();
exposedClass.possiblePrivateVariable;   // -> undefined.
exposedClass._possiblePrivateMethod();  // -> undefined.
exposedClass. myMethod();               // -> logs: am I a private method?
                                        //          am I a private variable?

It is obvious that those are feeling like beeing 'private' because I am not exposing them with the word export. My question is if this method can be considered creating private variables and methods? And if the Method I've shown has any other possible leakage while running the code?

Regards, Megajin


Sidenote: I do not need browser support since it is a NodeJS only environment. I am using NodeJS v8.1.4 and use babel in my npm start script so I can use import without any TypeError's.

I should mention as well that I'm aware that this question could be seen as a duplicate but it is not because this question is not about private properties, variables and methods inside a class but outside it.

Answer

Orelsanpls picture Orelsanpls · Aug 23, 2017

My question is if this method can be considered creating private variables and methods?

Yes it's an actual working solution to address the fact that ES6/7/8 do not handle privacy in classes.

And if the Method I've shown has any other possible leakage while running the code?

Fast answer : No leak

Detailed answer:

In your private function system, what makes the function private is that in javascript the scope of a function is defined by where it's defined. In your case the file.

If you do not export the function outside the file, there is no way to access it. Like you cannot access the function in the following mainstream example :

function toto() {
 const tmpToto = () => console.log('Hello');

 // I can access tmpToto from here
 tmpToto();

 return false;
}

// I cannot access tmpToto from here

Here you get a nice explanation about scopes


More infos according to comment

How would you solve the problem that multiple class instances will share the 'out of scope' variables?

You can use IIFE(Immediately-invoked function expression) as described by @Son JoungHo in this post.

let Name = (function() {
  const _privateHello = function() {}

  class Name {
    constructor() {}

    publicMethod() {
      _privateHello();
    }
  }

  return Name;
})();