最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Define 'real' private methods in ES6 ModuleClass in a nodejs only environment without any informati

programmeradmin0浏览0评论

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.

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.

Share Improve this question asked Aug 23, 2017 at 8:05 MegajinMegajin 2,7683 gold badges28 silver badges46 bronze badges 12
  • 1 Well, yes, but… that "private" variable is shared between all instances of the class. Which defeats the purpose of having a class with potentially several independent instances. You've just reduced it to a (non-)global variable. – deceze Commented Aug 23, 2017 at 8:20
  • 1 Those are no methods, they're not part of the instances. They're just static functions and variables local to the module. Which is fine, but most likely not what you were looking for. – Bergi Commented Aug 23, 2017 at 8:30
  • @deceze If I have 2 instances of the same class will the variables be overwritten by each other? – Megajin Commented Aug 23, 2017 at 9:07
  • 3 Your outward API, e.g. your HTTP interface, should be resistant to stuff like injection. Your inner API, which presumably is only accessible to developers you trust, doesn't need to be ironclad fortified against itself. Typescript's private annotations, or perhaps a simple naming convention like _thisIsPrivate, are enough to ensure privacy. Privacy is not a security mechanism in the first place; it's to keep code maintainable and extensible by defining stable public interfaces and unstable internal implementation details. – deceze Commented Aug 23, 2017 at 9:35
  • 1 You can't protect against developer stupidity. There are many more worse things any developer will do that will cost you time here and there. This is a problem to be solved at the process level (workflow), not the code level. E.g. have a CI server which piles TypeScript and reports errors; if you're correctly using private annotations, that'll catch that kind of problem. – deceze Commented Aug 23, 2017 at 9:53
 |  Show 7 more ments

1 Answer 1

Reset to default 6

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 ment

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

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论